CMK08 Posted October 14, 2008 Share Posted October 14, 2008 I am having trouble using this code I found on a different thread. If I force the download by redirecting the user with header(Location: file.zip) all works well, except that instead of getting a "download" dialog, the user gets a "now opening" dialog. With the code below, I get the "downloading" dialog, but the file gets corrupted. Can anyone spot the problem? thanks <?php // My Zip file to Download $zipfile = "myZip.zip"; header("Pragma: public"); // set expiration time header("Expires: 0"); // browser must download file from server instead of cache header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); // force download dialog header("Content-Type: application/force-download"); header("Content-Type: application/zip"); header("Content-Type: application/download"); // Display the save dialog to the user with the filename header("Content-Disposition: attachment; filename=".basename($zipfile).";"); // Shows a progress bar for the downloading file header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($zipfile)); @readfile($zipfile); ?> Quote Link to comment Share on other sites More sharing options...
MadTechie Posted October 14, 2008 Share Posted October 14, 2008 Nothing wrong with the code from what i can see.. do you have an online example or a damaged zip i can see ? whats the zip file size ? as a guess i would say the file is getting truncated or has some php output ie memory problems.. remember the <?php MUST be at the very start of the file.. Quote Link to comment Share on other sites More sharing options...
Orio Posted October 14, 2008 Share Posted October 14, 2008 Make sure there are no extra spaces/newlines outside of the php tags. The opening "<?php" should come at the first line. Also, add an "exit;" statement after readfile(). That should do it. Orio. Quote Link to comment Share on other sites More sharing options...
CMK08 Posted October 14, 2008 Author Share Posted October 14, 2008 I removed all spaces and added an exit(); at the end. Still not working. Check it out here: www.cristinamatos.com/downloads/zip.php. Quote Link to comment Share on other sites More sharing options...
Orio Posted October 14, 2008 Share Posted October 14, 2008 I've downloaded a file, opened it with notepad and got: <br /> <b>Warning</b>: filesize() [<a href='function.filesize'>function.filesize</a>]: stat failed for reports.zip in <b>/home/cristina/www/www/downloads/test.php</b> on line <b>10</b><br /> <br /> <b>Warning</b>: Cannot modify header information - headers already sent by (output started at /home/cristina/www/www/downloads/test.php:10) in <b>/home/cristina/www/www/downloads/test.php</b> on line <b>10</b><br /> Line 10 and it's area has nothing to do with filesize(). Can you show the full script? Orio. Quote Link to comment Share on other sites More sharing options...
CMK08 Posted October 14, 2008 Author Share Posted October 14, 2008 I moved that script back to my form, tried the download, and it looks like it is downloading the code instead of "reports.zip"... I did this locally, and this is what I got in the zip folder: <form action=zip.php method=post><p><input type="checkbox" name= 1 >contact.html</p><p><input type="checkbox" name= 2 >index.php</p> <p><input type="checkbox" name= 3 >re.txt</p><p><input type="checkbox" name= 4 >korean_test.pdf</p> <input type=submit name=submit value=Download></form>index.php<br>Archive created successfully. That would explain why the zip files from the website were blank after I removed the filesize line. Even though I am specifying a file to be downloaded, the code is trying to download the html page. test.php is supposed to handle the zip.php form: <?php $zipFile = 'reports.zip'; header('Pragma: public'); header('Cache-Control: must-revalidate, post-check=0'); header('Content-type: application/download'); header('Content-type: application/zip'); header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename='.basename($zipFile).';'); header('Content-Transfer-Encoding: binary'); //header('Content-Length: '.filesize($zipFile).';'); @read($zipFile); ?> Quote Link to comment Share on other sites More sharing options...
Orio Posted October 14, 2008 Share Posted October 14, 2008 First, there's no such function as read(). Should be readfile() I guess. Now, the reports.zip file is in the same folder as test.php? I can't think of a reason it'd give the previous error. How exactly can it show the HTML file? Are you sure you've showed the full script? Orio. Quote Link to comment Share on other sites More sharing options...
CMK08 Posted October 15, 2008 Author Share Posted October 15, 2008 It looks like a logical error on my form... <?php //this array is built with query result $fileList2= array('1'=>'contact.html','2'=>'index.php','3'=>'re.txt','4'=>'korean_test.pdf'); echo '<form action=zip.php method=post>'; foreach ($fileList2 as $value=>$name){ echo "<p><input type=\"checkbox\" name= $value >$name</p>"; } echo "<input type=submit name=submit value=Download></form>"; // after form is submitted: if(isset($_POST['submit'])){ //prepare list of items to zip $fileList = array(); foreach($fileList2 as $value=>$name){ if(isset($_POST[$value])){ $fileList[]= $name; } } //if at least one item was selected zip them up and send it to the browser if (!empty($fileList)){ // create object $zip = new ZipArchive(); // open archive if ($zip->open('reports.zip', ZIPARCHIVE::CREATE) !== TRUE) { die ("Could not open archive"); } $numFiles = $zip->numFiles; if($numFiles>0){ for ($x = 0; $x<$numFiles;$x++){ $file = $zip->statIndex($x); $zip->deleteIndex($x) or die("ERROR: Could not delete file"); } } $item = $fileList[0]; echo $item.'<br>'; // add files foreach ($fileList as $f) { $zip->addFile($f) or die ("ERROR: Could not add file: $f"); } // close and save archive $zip->close(); $filename='reports.zip'; //header('Location: reports.zip'); header('Pragma: public'); header('Cache-Control: must-revalidate, post-check=0'); header('Content-type: application/download'); header('Content-type: application/zip'); header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename='.basename('reports.zip').';'); header('Content-Transfer-Encoding: binary'); //header('Content-Length: '.filesize('reports.zip').';'); @read('reports.zip'); exit; } Else{ echo "you must select an item";}} else { echo "Please select the reports you would like to download";} ?> The message that should appear after the file has been created is ending up in the zip file that is downloaded. It is as if the zip folder is being downloaded before the files get in it. I checked this folder (which is in the same directory as the scripts) and the correct files are in it. Quote Link to comment Share on other sites More sharing options...
Orio Posted October 16, 2008 Share Posted October 16, 2008 Try it this way: <?php //this array is built with query result $fileList2= array('1'=>'contact.html','2'=>'index.php','3'=>'re.txt','4'=>'korean_test.pdf'); // after form is submitted: if(isset($_POST['submit'])) { //prepare list of items to zip $fileList = array(); foreach($fileList2 as $value=>$name){ if(isset($_POST[$value])){ $fileList[]= $name; } } //if at least one item was selected zip them up and send it to the browser if (!empty($fileList)){ // create object $zip = new ZipArchive(); // open archive if ($zip->open('reports.zip', ZIPARCHIVE::CREATE) !== TRUE) { die ("Could not open archive"); } $numFiles = $zip->numFiles; if($numFiles>0){ for ($x = 0; $x<$numFiles;$x++){ $file = $zip->statIndex($x); $zip->deleteIndex($x) or die("ERROR: Could not delete file"); } } $item = $fileList[0]; //echo $item.'<br>'; // add files foreach ($fileList as $f) { $zip->addFile($f) or die ("ERROR: Could not add file: $f"); } // close and save archive $zip->close(); $filename='reports.zip'; //header('Location: reports.zip'); header('Pragma: public'); header('Cache-Control: must-revalidate, post-check=0'); header('Content-type: application/download'); header('Content-type: application/zip'); header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename='.basename('reports.zip').';'); header('Content-Transfer-Encoding: binary'); //header('Content-Length: '.filesize('reports.zip').';'); @read('reports.zip'); exit; } else { echo "you must select an item"; } } echo '<form action="zip.php" method="post">'; foreach ($fileList2 as $value=>$name){ echo "<p><input type=\"checkbox\" name=\"{$value}\" >{$name}</p>"; } echo "<input type=\"submit\" name=\"submit\" value=\"Download\"></form>"; echo "<br>Please select the reports you would like to download"; ?> The thing is, if you are force downloading something you can't have any other output but the readfile's output. Otherwise, that data (you echoed) will be added to the zip file. I've changed a bit the structure of your main if clause. Also removed the echo you have in the middle of the script (I've commented it). Should be working now. Orio. Quote Link to comment Share on other sites More sharing options...
CMK08 Posted October 19, 2008 Author Share Posted October 19, 2008 Now I get an empty zip folder. It looks like the the files are placed in the zip folder after the zip folder has been downloaded. I am puzzled... Quote Link to comment Share on other sites More sharing options...
CMK08 Posted October 19, 2008 Author Share Posted October 19, 2008 I tested just this piece of the code: <?php $zipFile = 'reports.zip'; header('Pragma: public'); header('Cache-Control: must-revalidate, post-check=0'); header('Content-type: application/download'); header('Content-type: application/zip'); header('Content-Type: application/force-download'); header('Content-Disposition: attachment; filename='.basename($zipFile).';'); header('Content-Transfer-Encoding: binary'); //header('Content-Length: '.filesize($zipFile).';'); @read($zipFile); ?> While the zip folder does have files in it, the folder downloaded with this script is empty. I think I am missing something in this code. Quote Link to comment Share on other sites More sharing options...
Orio Posted October 19, 2008 Share Posted October 19, 2008 I've never had to use the ZIP library, but I guess the problem is there somehow, if you are getting an empty folder. Try going over the piece of code that creates the archive with the manual as a reference to see if you're doing it right. Orio. Quote Link to comment Share on other sites More sharing options...
CMK08 Posted October 19, 2008 Author Share Posted October 19, 2008 Orio, you were right. I don't know why the script didn't work the first time I tried with the edits you made. After trying several different things, I ended up moving the form tags to the end (like you did) and now it works. The only difference between your edits and mine are the escaped quotes. I must have missed something when using your solution. Thank you very much! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.