6

I have this code

<?php
$files = array('includes/s.xlsx', 'includes/test.html');
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
  $zip->addFile($file);
 }
$zip->close();


header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=filename.zip');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);

But i don't want to make the zip file saved to the server i just want it to be served to the users.

3 Answers3

7

ZIP is not a streamable format (the target needs to support seeking, i.e. a ZIP file cannot be simply written to a target where the previously-written data cannot be re-read and modified) what you are trying to do can't work. So the best solution (if your zip files won't be huge) is creating it in a temporary location, readfile() it and then delete the temporary file.

See the following Stack Overflow questions for further reference. They contain some workarounds that might be fine for you:

Community
  • 1
  • 1
ThiefMaster
  • 285,213
  • 77
  • 557
  • 610
4

Try adding this after readfile($zipname); :

// delete the file from the server
unlink($zipname);
exit;
Iamirm
  • 53
  • 4
3

You're using the object $zip to open and modify the zip file, but filesize() and readfile() only work on file names, so you should have this:

header('Content-Length: ' . filesize($zipname));
readfile($zipname);

Btw, you can use tempnam() to generate a "temporary" file that will be used to hold the zip contents; once readfile() is done you still have to unlink() it though.

Ja͢ck
  • 161,074
  • 33
  • 239
  • 294