Justice
Justice

Reputation: 179

PHP Zip file download error when opening

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

Answers (6)

Daniel Amado
Daniel Amado

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

Gombo
Gombo

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

Anamika Gupta
Anamika Gupta

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

Sweet Chilly Philly
Sweet Chilly Philly

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

Fabien Thetis
Fabien Thetis

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

user1864610
user1864610

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

Related Questions