7

I am getting zip file downloaded by following code without any error but the downloaded zip file is empty or corrupted and size is always about 200 Bytes. i.e. I cannot open that zip file. Also ZipArchive::getStatusString() is also showing "No error"

code is :

public function getzip(){
    global $config;
    $files=array();
    if(isset($_COOKIE['hashes'])){
        $hashes=explode(',',$_COOKIE['hashes']);
        for ($i=0; $i <count($hashes); $i++) {
            array_push($files,$config["domain"]."/download/".$hashes[$i]); 
        }
    }
    if(count($files)){
        $zipname='basket.zip';
        $zip = new ZipArchive;
        $zip->open($zipname,ZipArchive::CREATE);
        foreach ($files as $key=>$value ) {
            $zip->addFile($value);
        }
        $status=$zip->getStatusString();
        $zip->close();

    if(!$zipname)
    {
        echo "Nothing in Basket";
    }
    else
    {   header('Content-Description: File Transfer');
        header('Content-Type: application/zip');
        header('Content-Disposition:attachment; filename='.basename($zipname));
        header('Content-Length:'.filesize($zipname));
        readfile($zipname);
    }
}
Durgesh Suthar
  • 2,914
  • 4
  • 19
  • 22
  • its giving me false. this means directory of $zipname is not created. But m not getting msg of "Nothing in Basket" instead getting a zip file downloaded. – Durgesh Suthar Feb 09 '13 at 22:23

8 Answers8

5

Try getting the full file path and name just before $zip->close();

$filename = $zip->filename;

And use that instead of $zipname when reading the file and getting the file size

nice ass
  • 16,471
  • 7
  • 50
  • 89
3

This is my best guess. What's going wrong here is that in your array $files the values you're storing are probably not actual paths to files.

Remember: You can't pass URLs into $zip->addfile(), you need your actual files.

worldofjr
  • 3,868
  • 8
  • 37
  • 49
Rushil
  • 135
  • 1
  • 6
1

Even tough this question has been figured out, I will post what I found out how corrupted zips can be created:

When making a zip archive you will often debug with echo/print_r commands. If you dont clear these out, the output zip file will be corrupt.

Example based on the question:

public function getzip(){
    global $config;
    $files=array();
    if(isset($_COOKIE['hashes'])){
        $hashes=explode(',',$_COOKIE['hashes']);
        for ($i=0; $i <count($hashes); $i++) {
            array_push($files,$config["domain"]."/download/".$hashes[$i]); 
        }
    }
    if(count($files)){
        $zipname='basket.zip';
        $zip = new ZipArchive;
        $zip->open($zipname,ZipArchive::CREATE);
        foreach ($files as $key=>$value ) {
            $zip->addFile($value);
        }
        $status=$zip->getStatusString();
        $zip->close();

    if(!$zipname)
    {
        echo "Nothing in Basket";
    }
    else
    {   
        // to fix your corrupt zip file, remove this line.
        echo 'THIS IS AN EXAMPLE DEBUG: ' . $zipname;
        header('Content-Description: File Transfer');
        header('Content-Type: application/zip');
        header('Content-Disposition:attachment; filename='.basename($zipname));
        header('Content-Length:'.filesize($zipname));
        readfile($zipname);
    }
}
Igor L.
  • 3,159
  • 7
  • 40
  • 61
1

Adding to this thread even though the original problem has been solved since I just spent a couple of hours with a similar problem.

It turns out the files all need to exist when doing $zip->close(), regardless of when you use $zip->addFile() to add them.

So if you create temporary files, add them to your zip and then delete them before you have used close(), you might end up with an empty/corrupted archive.

John Severinson
  • 5,145
  • 1
  • 16
  • 6
1

Probably this is not useful for OP but i came across this problem when changes my virtual server. I do not know what changed in server setups but zip started to make empty zips.

After some research and testing i found out that all i needed to do is add file name (i do not know why it worked on old server) as second parameter:
$zip->addFile($value, $zipname); // $zipname in this case

Another issue i had was that i had too low memory_limit

Hope this helps!

Ingus
  • 1,026
  • 12
  • 34
0

I solved the same issue by moving the code to the same folder where the files that I wanted to add to the Zip archive were located.

Israel T.
  • 1
  • 1
0

In my case, the problem was down to passing a value of '/' in the add_path option for the ZipArchive::addGlob() method:

    $zipArchive->addGlob($tmpFolder . DIRECTORY_SEPARATOR ."*", 
                         0, 
                         ['add_path' => '/', 'remove_all_path' => true]);

Removing that solved the problem for me:

    $zipArchive->addGlob($tmpFolder . DIRECTORY_SEPARATOR ."*", 
                         0, 
                         ['remove_all_path' => true]);
John Rix
  • 6,271
  • 5
  • 40
  • 46
0

In my case, the problem was down to passing the file name as a second argument. I believe since the code it was executed on a linux server, the "/" in the filepath were causing problems in opening the zip file in windows. Providing a file name as a second argument solved the issue.

if( file_exists($FILEPATH) && is_readable($FILEPATH) && filesize($FILEPATH) > 0 ){
          if ( $zip->addFile($FILEPATH, $FILENAME) != TRUE ) {
              die("Could not open $FILENAME");
          }
}
Niko Zarzani
  • 1,372
  • 2
  • 15
  • 28