问题
I set a header in the following way:
header('Content-Length: ' . filesize($strPath));
On my PC with ZendServer it works fine and I can download a file with the correct file size. On the production server, a Solaris with Apache and compiled PHP, I get a file with the file size equal to zero, so an empty file.
Is there a config parameter? Something that can prevent to set 'Content-Length: 1222'?
Thanks.
The code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
require 'includes/prepend.inc.php';
require __ADMIN_DIR__.'/AdminInfo.php';
$intFile = QApplication::QueryString('fileID');
if($intFile == '') die('Error: missing ID');
$objFile = File::Load($intFile);
$blnRight = false;
$objAdminInfo = new AdminInfo();
if($objAdminInfo->isAdmin()) {
$blnRight = true;
}
else {
$objSecMan = new SecurityManager(
'file:'.$objFile->FileID,
$objAdminInfo->getUserID()
);
$blnRight = $objSecMan->processResource('view');
}
// if the user can modify and or publish, can even view the file
if(!$blnRight) {
$blnRight = $objSecMan->processResource('modify');
if(!$blnRight) {
$blnRight = $objSecMan->processResource('publish');
}
}
//$strPath = __UPLOADS__.DIRECTORY_SEPARATOR.$objFile->FileID;
$strPath = 'subdept.csv';
if (file_exists($strPath) && $blnRight) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$strPath);//$objFile->Filename);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($strPath));
ob_clean();
flush();
readfile($strPath);
exit;
}
else {
die('Restricted access');
}
?>
When I comment the code before $strPath it works, so it must be something in the bloody framework. I would like to throw the whole CMS away.
回答1:
Check for transfer-encoding header. If the transfer encoding is chunked, then the Content-Length field will not be set
Possible causes, is that ZendServer does not do chunked encoding, whereas Apache does
See the following links for details
http://en.wikipedia.org/wiki/Chunked_transfer_encoding
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html
回答2:
Make sure that the file really exists under the specified path (is_file checks both the existance and if the file is a regular file) and is readable (is_readable) before sending it to the client. filesize returns false if an error occured. So that might be the cause of your 0 value or empty value for Content-Length.
And, as Ferdinand Beyer already mentioned, make sure that your script is portable and can handle different environments.
回答3:
Are you sure the file exists on the production server? Maybe it's a case sensitivity issue (e.g, "File" and "file" are the same on Windows, but different on UNIX)? Does the user running Apache/PHP have read access?
回答4:
Do you get any errors if you enable errors?
error_reporting(E_ALL);
ini_set('display_errors', '1');
回答5:
A problem may be that Apache is gzipping your download, taking care of correcting the Content-Length, or in your case, removing that header and adding
Content-Encoding: chunked
You can add a .htaccess
RewriteRule to disable gzip:
RewriteRule . - [E=no-gzip:1]
来源:https://stackoverflow.com/questions/1334471/content-length-header-always-zero