6

So what I am trying to do is take 2 strings and create 2 files. Then create a zip out of these files and let a user download them.

Here is what I have:

$string1 = 'Some data some data some data';
$string2 = 'Some data some data some data';


$zip = new ZipArchive();
$filename = "test.zip";

if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
   exit("cannot open <$filename>\n");
}


$zip->addFromString("string1.txt", $string1);
$zip->addFromString("string2.txt", $string2);
$zip->close();

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize('test.zip'));

So far no luck. Any help is appreciated.

chiminage
  • 87
  • 2
  • 7
  • 1
    `$zip->addFromString("string2.txt", $string1);` should be `$zip->addFromString("string2.txt", $string2);` – Patashu Mar 07 '13 at 00:34
  • 2
    I'm not seeing where you actually *transmit* the zip you create? – Francis Avila Mar 07 '13 at 00:38
  • hmm....what should I do to transmit? – chiminage Mar 07 '13 at 00:39
  • Please enable error logging, set the level high, follow your error log. Fix the errors reported. If you then still miss the point, edit your question and make it precise. PHP normally tells you where problems are, all you need to do is to read the error messages. http://stackoverflow.com/questions/845021/how-to-get-useful-error-messages-in-php – hakre Mar 07 '13 at 00:41

3 Answers3

9

You missed the most important part - output the file! :)

Add:

readfile('test.zip');

to the end of the php file.


Also the calculation of the HTTP content-length header is wrong:

header("Content-Length: ".filesize($zip));

This will give you always 0 ( or false) as filesize expects a filename as its argument.

Change the line to:

header("Content-Length: ".filesize('test.zip'));

After doing both of this the zip will successfully download and contains the two files. For completenes, here comes the full working example:

$string1 = 'Some data some data some data';
$string2 = 'Some data some data some data';


$zip = new ZipArchive();
$filename = "test.zip";

if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
   exit("cannot open <$filename>\n");
}


$zip->addFromString("string1.txt", $string1);
$zip->addFromString("string2.txt", $string1);
$zip->close();

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
// make sure the file size isn't cached
clearstatcache();
header("Content-Length: ".filesize('test.zip'));
// output the file
readfile('test.zip');
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Yah...I changed that but Im still getting a zip file that when you open it it brings up another zip and it seems to be a loop – chiminage Mar 07 '13 at 00:41
  • You are welcome. Sometimes one oversees the most important things ;) (I also missed to check this first when reading the question and first saw the filesize issue.. Don't forget to fix that too) – hek2mgl Mar 07 '13 at 00:49
1

You have a PHP error (you probably dont have error reporting turned on or high enough error level).

the filesize() function takes a string not an object. filesize($filename) will work.

to turn on error reporting do:

error_reporting(E_ALL|E_STRICT); ini_set('display_errors', 1);

alternatively do this in php.ini

Michael Parkin
  • 1,855
  • 2
  • 12
  • 13
1

After all those header() calls, I think you want:

readfile($filename); 
Bob Stein
  • 16,271
  • 10
  • 88
  • 101