5

I'm trying to create a zip file with directory tree based on array strutucture.

I already use this answer when I need to create a zip file from a directory tree, but in this case all the files are in the same directory and the directory tree is based on other data from database.

I've checked that all files are in the correct path and that the foreach loops are working. The error is happening with $zip->close.

That's the code (the original array has many entries in each level):

$zip_array = array( 'Level 1' =>  array( 
                    'Level 2' => array ( 
                            'file 1' => '/var/www/html/pdf/683026577.pdf',
                            'file 2' => '/var/www/html/pdf/683026578.pdf'
                            'file 3' => '/var/www/html/pdf/683026579.pdf'
                            )
                    )
        );
$destination = 'testzip.zip';
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        echo "fail";
    }
foreach ($zip_array as $key => $level2){
    $lev1 = '/'.$key.'/';
    $zip->addEmptyDir($lev1);
    foreach ($level2 as $key => $level3){
        $lev2 = $level1 . $level2.'/';
        $zip->addEmptyDir(lev2);
        foreach ($level3 as $key => $file){
            $lev3 = $lev2 . $key.'.pdf';
                    $zip->addFile($file, $lev3); 
        }
    }
}
$close = $zip->close();
if ($close){
    echo "Ok"
}else{
    echo "Fail";
}
Community
  • 1
  • 1
Ricardo Gonçalves
  • 4,344
  • 2
  • 20
  • 30
  • 1
    Can you add the error message to you're post? We can't help if we don't know what the error is. Also, it seems wrong to me to prepend `'/'` to `$lev1` at the beginning of your foreach loop. That could be the problem... – mkasberg May 20 '15 at 16:53
  • 1
    Actually there's no error message... the $zip->close() just returns false... the $zip->open() returns true, so it's not a permissions problem... I've removed the first `/`, but it's still not working... – Ricardo Gonçalves May 20 '15 at 17:15
  • 2
    Try using this before/after close to debug: http://php.net/manual/en/ziparchive.getstatusstring.php – mkasberg May 20 '15 at 19:06
  • 2
    Great tip! getstatussrting output that It was a permission problem. The owner of the path was root. Weird that it didn't trigger the error in $zip->open. Could you please post an answer with this tip? – Ricardo Gonçalves May 20 '15 at 20:08

3 Answers3

6

Error handling in PHP is a little strange sometimes. If the close() function returned false, there was an error, but it won't explicitly tell you what the error was. Use ZipArchive::getStatusString to get the status of your $zip object. That will tell you exactly what the error was, and you can then take steps to fix the problem.

This pattern of checking for an error status when false is returned is fairly common in PHP - especially with older code that may have been written before PHP had good exception handling support.

mkasberg
  • 16,022
  • 3
  • 42
  • 46
0

As a workaround you can use $zip->close() ?: ZipArchive::ER_CLOSE which will not give the reason for the fail, but can be useful if you only need to handle the failure.

$zip = new ZipArchive();
$res = $zip->open($filename, ZIPARCHIVE::OVERWRITE | ZIPARCHIVE::CREATE);
if ($res === true)
    $res = $zip->addFromString('temp', 'a');
if ($res === true)
    $res = $zip->close() ?: ZipArchive::ER_CLOSE;
if ($res === true)
    echo 'success.';
else
    echo 'failed: ' . GetZipErrMessage($res);

p.s: GetZipErrMessage can be found here.

oriadam
  • 7,747
  • 2
  • 50
  • 48
0

For me the ZipArchive PHP: Close() returns false with no error... was because of folder permission issues. you need to have the directory created and with the correct permissions before you start to store the zip file inside it.

Ahmad Mobaraki
  • 7,426
  • 5
  • 48
  • 69