Reputation: 179
I need to download a zip file from a website as I am going to require to coalesce multiple files in a single download (up to 100 individual files-ish).
When attempting to create the zip file, it downloads as intended, the file name appears in the format "YYYY.MM.DD - HH.MM.SS" also as intended. My issue occurs when attempting to open the zip file in windows 7 (or winzip) - I get the error message below. This happens repeatedly from multiple attempts.
I assume that I have made an error while coding the creation or download of the zip file, rather than the zip file format itself being an issue as I can open different zip files - can anyone see the mistake I have probably made? (code included below error image)
I have attempted to use Download multiple files as a zip-file using php as a reference.
//backup file name based on current date and time
$filename = date("Y.m.j - H.i.s");
//name of zip file used when downloading
$zipname = 'temp.zip';
//create new zip file
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
//yes, I know the zip file is empty currently - I've cut the code from here for
//now as the zip file doesn't function with / without it currently
$zip->close();
//download file from temporary file on server as '$filename.zip'
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$filename.'.zip');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
Upvotes: 3
Views: 13673
Reputation: 1
$zip->close();
ob_clean(); // <-- this is the asnwer
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$nombreDir.'.zip');
header('Content-Length: ' . filesize($directorioCreado . '.zip'));
header('cache-control: no-cache, must-revalidate');
header('Expires: 0');
readfile($directorioCreado . '.zip');
Upvotes: 0
Reputation: 748
In my case this worked
put this at the beginning of the php file
ob_start();
then, after the headers and immediately before the readfile put this
while (ob_get_level()) {
ob_end_clean();
}
wrapping up
ob_start();//this is new
//backup file name based on current date and time
$filename = date("Y.m.j - H.i.s");
//name of zip file used when downloading
$zipname = 'temp.zip';
//create new zip file
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
//yes, I know the zip file is empty currently - I've cut the code from here for
//now as the zip file doesn't function with / without it currently
$zip->close();
//download file from temporary file on server as '$filename.zip'
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$filename.'.zip');
header('Content-Length: ' . filesize($zipname));
while (ob_get_level()) {//this is new
ob_end_clean();//this is new
}//this is new
readfile($zipname);
Upvotes: 0
Reputation: 81
try to add ob_end_clean(); before headers
<?php
$zip = new ZipArchive();
$zip_name = $name.".zip"; // Zip name
$tmpFile=APPPATH.'../'.$zip_name;
$zip->open($zip_name, ZipArchive::CREATE);
foreach ($images as $files) {
if(!empty($files->cloudinary_img_url)){
$zip->addFromString(basename($files->car_images), file_get_contents(getImagesDropbox($files->cloudinary_img_url)));
}
else{
echo"file does not exist";
}
}
$zip->close();
ob_end_clean();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename="'.$zip_name.'"');
header('Content-Length: ' . filesize($tmpFile));
readfile($tmpFile);
unlink($tmpFile);
?>
Upvotes: 1
Reputation: 3219
I had this issue, but this solution fixed it for me
Add ob_clean(); just before your new output headers.
I am using an older version of Silverstripe and my zip files were constantly being corrupted even though the data was visibly in there.
The solution of this obscure comment above to use ob_clean(); was helpful, and I wanted to pull this out as an Answer to this question.
From PHP docs:
ob_clean();
discards the contents of the output buffer.
ob_clean();
does not destroy the output buffer like ob_end_clean() does.
Upvotes: 2
Reputation: 1734
Try to open the zip file with a text editor. This way you can check if were is a php error in your code (during the compression step).
Upvotes: 7
Reputation:
Check that the web server user has write permission to the folder where you're creating the ZIP file. Notwithstanding the documentation, ZipArchive::open()
will fail silently and return true
(i.e. success) if it cannot create the ZIP file. Further, ZipArchive::addFile()
will seemingly add as many files as you wish to this non-existent archive, also without reporting an error. The first point at which an error appears is when ZipArchive::close() returns `false'. No error messages appear in the error logs, either.
Readfile()
will report an error to the logs and fail, so the result is a zero-length ZIP file on your local hard disk.
The reason seems to be that the ZipArchive class is only assembling a list of files in memory until it's closed, at which point it assembles all the files into the Zip file. If this can't be done then ZipArchive::close()
returns false
.
Note: if the zip file is empty, it might not be created at all! Your download will proceed, but readfile()
will fail and you'll get a zero-length ZIP file downloaded.
What to do?
Add a little error checking to your code to report some of this:
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
// Add your files here
if ($zip->close() === false) {
exit("Error creating ZIP file");
};
//download file from temporary file on server as '$filename.zip'
if (file_exists($zipname)) {
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$filename.'.zip');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
} else {
exit("Could not find Zip file to download");
}
Upvotes: 3