2

Everything works fine on localhost, but when I try to get this script to work on server I couldn't. I tried to change permission of root and uploads (where uploaded images are and where .zip files should be created) to 777 (I know it's not safe, but I just tried to test because it worked on localhost) but it doesn't. I also don't get any additional errors, and error reporintg (E_ALL) is turned on in php.ini. Directories are also created normally in that folder via mkdir() function.

Here is the function for zipping folders:

function Zip($source, $destination)
{

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

if (Zip($folder.$archiveName."/", $folder.$archiveName.".zip")) {
    echo "Done.";
    rrmdir($folder.$archiveName."/");
} else {
    addError("Error while trying to compress files.");
}

I also tried to write out the error message:

if ($zip->close()) {
    echo "Done.";
}
else {
    echo $zip->getStatusString();
}

But it doesn't write out anything.

Nikola Stojaković
  • 2,257
  • 4
  • 27
  • 49

2 Answers2

1

Problem is solved - I localized problem with debugging and realized that zip extension wasn't loaded. In case you encounter this problem too (site is deployed on DigitalOcean) and you're using Debian or derivative just install php7.0-zip package:

sudo apt-get install php7.0-zip
Nikola Stojaković
  • 2,257
  • 4
  • 27
  • 49
0

Another possible cause for ZipArchive::close to return false can be caused by file permissions on any of the files being added to the archive.

If PHP can't open the file added to the archive, ZipArchive::addFile() will return true, but when ZipArchive::close() is called you will get:

"Warning: ZipArchive::close(): Can't open file: Permission denied"

More details in this comment from the PHP Manual:

https://www.php.net/manual/en/ziparchive.addfile.php#101605

Beware: calling $zip->addFile() on a file that doesn't exist will succeed and return TRUE, delaying the failure until you make the final $zip->close() call, which will return FALSE and potentially leave you scratching your head.

If you're adding multiple files to a zip and your $zip->close() call is returning FALSE, ensure that all the files you added actually exist.

It's also a good idea to check each file with file_exists() or is_readable() before calling $zip->addFile() on it.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 31 '22 at 10:32