Download of .zip file runs a corrupted file php
Solution 1
This issue can have several causes. Maybe your file is not found or it can not be read and thus the file’s content is just the PHP error message. Or the HTTP header is already sent. Or you have some additional output that then corrupts your file’s content.
Try to add some error handling into your script like this:
$file='../downloads/'.$filename;
if (headers_sent()) {
echo 'HTTP header already sent';
} else {
if (!is_file($file)) {
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
echo 'File not found';
} else if (!is_readable($file)) {
header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
echo 'File not readable';
} else {
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: ".filesize($file));
header("Content-Disposition: attachment; filename=\"".basename($file)."\"");
readfile($file);
exit;
}
}
Solution 2
I bet two beers that a PHP error occurs, and the error message messes up the ZIP file. The requested file probably doesn't exist.
Open the ZIP file with notepad or a similar text editor, and find out what's wrong.
Solution 3
Late answer but maybe useful for users not being able to make force download
work.
Add the following at the top of your php
script
<?php
apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 0);
Solution 4
I had similar problems for large zip files This works for me:
In your php.ini, change to:
- Upload_max_filesize - 1500 M
- Max_input_time - 1000
- Memory_limit - 640M
- Max_execution_time - 1800
- Post_max_size - 2000 M
In your php file.
$filename = "MyFile.zip";
$filepath='../downloads/'.$filename; //your folder file path
header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: Binary");
header("Content-Length: ".filesize($filepath));
header("Content-Disposition:attachment;filename=\"".basename($filepath)."\"");
while (ob_get_level())
{
ob_end_clean();
}
readfile($filepath);
exit;
ob_start ();
Solution 5
Here is the solution create a file with name .htaccess write below line in that SetEnv no-gzip dont-vary
upload the file to your website. If you have the file already there then please make the above change in that
Troy
Updated on October 17, 2020Comments
-
Troy over 3 years
I'm trying to force a download of a protected zip file (I don't want people to access it without logging in first.
I have the function created for the
login
and such , but I'm running into a problem where the downloaded file is corrupting.Here's the code I have:
$file='../downloads/'.$filename; header("Content-type: application/zip;\n"); header("Content-Transfer-Encoding: Binary"); header("Content-length: ".filesize($file).";\n"); header("Content-disposition: attachment; filename=\"".basename($file)."\""); readfile("$file"); exit();
Here's the error:
Cannot open file: It does not appear to be a valid archive.
The file downloads fine otherwise, so it must be something I'm doing wrong with the headers.
Any ideas?
-
prodigitalson over 14 yearsid agree i bet there is an error in the
readfile()
like invalid permissions, or it can be found... -
Troy over 14 yearsAwesome Gumbo! That answered it. That was it... I think the sent headers is the reason why it wasn't working.
-
Rajib Sarker about 4 yearsopening with notepad to see the error message was a life-saver. thanks man! :)
-
Momoro about 4 years@Gumbo My file does exist, but for some reason it returns a 'File Not Found'? Any ideas?
-
Ivan Shumakov almost 3 yearsIt works for me just because of "while" section. Anyway, what it means "while ob_get_level ob_end_clean"?
-
borgomeister over 2 yearsob_get_level — Return the nesting level of the output buffering mechanism ob_end_clean — Clean (erase) the output buffer and turn off output buffering
-
Willt42 over 2 yearsThis answer gave me the idea that maybe ANY output at all (not just errors) might mess up the Zip file. Turns out my echo statements were messing it up. Removed all echo's and voila it works.
-
LUISAO about 2 yearsThank you @Pekka. It has a message inside my file. So, i get the manual PHP and a user marro at cz put --- ob_clean(); flush(); --- before the readfile(). It Works!
-
LUISAO about 2 yearsRead message from @Pekka. It has a message inside my file. So, i get the manual PHP and a user marro at cz put --- ob_clean(); flush(); --- before the readfile(). It Works!