Getting corrupted or empty zip by ZipArchive php

13,136

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

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);
    }
}
Share:
13,136
Durgesh Suthar
Author by

Durgesh Suthar

Graduate from IIT Roorkee.

Updated on June 13, 2022

Comments

  • Durgesh Suthar
    Durgesh Suthar almost 2 years

    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
    Durgesh Suthar about 11 years
    @Pony Check this also.. Still getting same problem. I think Directory for the file is not being created. Also i checked 'var_dump($filename)' is show exact path.
  • nice ass
    nice ass about 11 years
    Did you assign this variable before calling $zip->close() ?
  • Scott
    Scott about 11 years
    Worked like a charm! Thanks :)
  • Ashutosh Gupta
    Ashutosh Gupta over 5 years
    removing echo and print_r statements worked for me... Thanks :)