I use this code to enable users to download a zip file:
if(file_exists($filename)){
header("Content-Disposition: attachment; filename=".basename(str_replace(' ', '_', $filename)));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($filename));
flush();
$fp = fopen($filename, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush();
}
fclose($fp);
exit;
}
When the file is downloaded, it only downloads 25,632 kilobytes of data. However the zip file is 26,252 kilobytes ...
Why does the browser get all 25MB but then stop?
I checked the Content-Length
header to make sure it was correct and it is...
In firefox, when i download the file, it says 'of 25mb' SO the browser thinks that 25mb is the COMPLETE amount... however, the content-length when echo'd is 26252904?
Use a single MIME type to represent the data.
In this case using application/octet-stream
will do just fine. This is when you dont know the MIME before hand. When you know it, you must put it. Do not use multiple content-type headers.
Usually, when the browser doesn't know how to handle a particular MIME, it will trigger the download process. Further, using Content-disposition: Attachment; ..
ensures it.
There exists a simple readfile($filename)
which will send out the bytes of the file to the requesting process like below:
header("Content-disposition: attachment;filename=" . basename($filename);
readfile($filename);
Your header('Content-Type ...)
calls are useless as only the last one will be sent to the browser.
Downloads are triggered by Content-Disposition: attachment
. You should send the actual Content-Type: application/zip
if you are sending a zip file.
Finally, your read loop is unnecessary.
Putting it all together, your code should look like this:
if (file_exists($filename)) {
$quoted_filename = basename(addcslashes($filename, "\0..\37\"\177"));
header("Content-Disposition: attachment; filename=\"{$quoted_filename}\"");
header('Content-Type: application/zip');
header('Content-Length: '.filesize($filename));
readfile($filename);
}
I had similar problem. The file downloaded fine in Firefox but not in IE. It appeared that Apache was gzipping the files and IE was not able to ungzip so the files were corrupted. The solution was to disable gzipping in Apache. You can also check if PHP is not gzipping on the fly and disable it too. For Apache you can try:
SetEnv no-gzip 1
And for PHP, in .htaccess:
php_flag zlib.output_compression on
This answer is by No means a REAL ANSWER.
However i did get it to work... I just set the Content-Length to 30000000. Therefor it thinks the file is bigger than it actually is, and then it downloads it all.
Ugly hack i know, but i couldn't find ANY other way
add this before your code
ob_clean();
ob_end_flush();