Getting corrupted or empty zip by ZipArchive php
Asked Answered
P

8

8

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);
    }
}
Pall answered 9/2, 2013 at 22:1 Comment(1)
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.Pall
T
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.

Thought answered 10/2, 2013 at 12:29 Comment(0)
S
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

Sidekick answered 9/2, 2013 at 22:21 Comment(2)
@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.Pall
Did you assign this variable before calling $zip->close() ?Sidekick
T
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.

Thought answered 10/2, 2013 at 12:29 Comment(0)
S
3

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);
    }
}
Split answered 26/8, 2013 at 10:45 Comment(2)
removing echo and print_r statements worked for me... Thanks :)Douty
Thank you !!! Removing all echo lines, fixed my problem. Thank again.Importunity
C
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.

Checky answered 2/3, 2017 at 15:33 Comment(0)
A
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!

Aeschylus answered 1/10, 2019 at 7:29 Comment(0)
W
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.

Wineglass answered 28/12, 2017 at 11:44 Comment(0)
U
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]);
Untouchable answered 28/2, 2020 at 11:56 Comment(0)
I
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");
          }
}
Irresolute answered 12/6, 2023 at 13:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.