7

I'm failing to put even a single file into a new zip archive.

makeZipTest.php:

<?php

$destination = __DIR__.'/makeZipTest.zip';
$fileToZip = __DIR__.'/hello.txt';

$zip = new ZipArchive();
if (true !== $zip->open($destination, ZIPARCHIVE::OVERWRITE)) {
    die("Problem opening zip $destination");
}
if (!$zip->addFile($fileToZip)) {
    die("Could not add file $fileToZip");
}
echo "numfiles: " . $zip->numFiles . "\n";
echo "status: " . $zip->status . "\n";
$zip->close();

The zip gets created, but is empty. Yet no errors are triggered.

What is going wrong?

Jodes
  • 14,118
  • 26
  • 97
  • 156
  • The code works - so I'd look at the permissions of the zip file and it's directory. – l'L'l Aug 12 '15 at 05:43
  • Thanks - but the script makes a temporary directory, makes a sub directory puts the file to be zipped into that sub directory, then zips that file from there into a zip in the temporary directory. So I can't fathom why it should have any permission issues since it's having no trouble making the directories or putting files in them?! – Jodes Aug 12 '15 at 05:47
  • Hmmm... maybe you should post the rest of the script then, since this part is working *(at least on linux). The only other thing I can think of at the moment given the info you've just mentioned is that maybe there's a race condition... – l'L'l Aug 12 '15 at 17:33
  • ziparchive has some major issues in php. What is the filesize of the created zip? is it a size similar to what you expect? try opening the resultant zip file in notepad++ are the first 2 chars null space ? if they are delete null space then attempt opening zip file again. are your files there as you would expect ? – Dave Aug 14 '15 at 15:36
  • @Dave, it seems that the zip file is of the expected size! But the first two characters are not null. I tried compressing different files and all of them start with: PK[EXT][EOT][DC4][NUL][NUL][NUL][BS][NUL] – Jodes Aug 15 '15 at 06:21

3 Answers3

14

It seems on some configuration, PHP fails to get the localname properly when adding files to a zip archive and this information must be supplied manually. It is therefore possible that using the second parameter of addFile() might solve this issue.

ZipArchive::addFile

Parameters

  • filename
    The path to the file to add.
  • localname
    If supplied, this is the local name inside the ZIP archive that will override the filename.

PHP documentation: ZipArchive::addFile

$zip->addFile(
    $fileToZip, 
    basename($fileToZip)
);

You may have to adapt the code to get the right tree structure since basename() will remove everything from the path apart from the filename.

Community
  • 1
  • 1
spenibus
  • 4,339
  • 11
  • 26
  • 35
1

You need to give server right permission in folder where they create zip archive. You can create tmp folder with write permision chmod 777 -R tmp/

Also need to change destination where script try to find hello.txt file $zip->addFile($fileToZip, basename($fileToZip))

<?php

$destination = __DIR__.'/tmp/makeZipTest.zip';
$fileToZip = __DIR__.'/hello.txt';

$zip = new ZipArchive();
if (true !== $zip->open($destination, ZipArchive::OVERWRITE)) {
  die("Problem opening zip $destination");
}
if (!$zip->addFile($fileToZip, basename($fileToZip))) {
  die("Could not add file $fileToZip");
}
echo "numfiles: " . $zip->numFiles . "\n";
echo "status: " . $zip->status . "\n";
$zip->close()
mlivan
  • 671
  • 3
  • 15
  • It'd be good to test if the zip file already exists, so then you decide if using ZipArchive::OVERWRITE or ZipArchive::CREATE – al'ein Aug 14 '15 at 16:11
  • 2
    @AedixRhinedale, the documents imply that both `OVERWRITE` and `CREATE` should work whether there's an existing file or not. The difference is simply whether the existing contents of the zip if it exists are replaced or added to. – Jodes Aug 15 '15 at 06:23
1

check this class to add files and sub-directories in a folder to zip file,and also check the folder permissions before running the code, i.e chmod 777 -R zipdir/

HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip'); 

<?php 
class HZip 
{ 

private static function folderToZip($folder, &$zipFile, $exclusiveLength) { 
$handle = opendir($folder); 
while (false !== $f = readdir($handle)) { 
  if ($f != '.' && $f != '..') { 
    $filePath = "$folder/$f"; 
    // Remove prefix from file path before add to zip. 
    $localPath = substr($filePath, $exclusiveLength); 
    if (is_file($filePath)) { 
      $zipFile->addFile($filePath, $localPath); 
    } elseif (is_dir($filePath)) { 
      // Add sub-directory. 
      $zipFile->addEmptyDir($localPath); 
      self::folderToZip($filePath, $zipFile, $exclusiveLength); 
    } 
  } 
} 
closedir($handle); 
} 


public static function zipDir($sourcePath, $outZipPath) 
{ 
$pathInfo = pathInfo($sourcePath); 
$parentPath = $pathInfo['dirname']; 
$dirName = $pathInfo['basename']; 

$z = new ZipArchive(); 
$z->open($outZipPath, ZIPARCHIVE::CREATE); 
$z->addEmptyDir($dirName); 
self::folderToZip($sourcePath, $z, strlen("$parentPath/")); 
$z->close(); 
} 
}