Search code examples
phpzipphp-ziparchive

Zip files need to include empty folders


I currently have this directory structure:

upload-here
upload-here/258/Image1.jpg
upload-here/259/Image2.jpg
upload-here/260/NO IMAGE
upload-here/261/somepicturename.jpg

etc etc. I am using the code shown below to make a backup of the upload-here folder by zipping it up.

<?php
// Get real path for our folder
$rootPath = realpath('/full-path-to/upload-here/');

// Initialize archive object
$zip = new ZipArchive();
$zip->open('upload-here.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);

// Create recursive directory iterator
/** @var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootPath),
    RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($files as $name => $file)
{
    // Skip directories (they would be added automatically)
    if (!$file->isDir())
    {
        // Get real and relative path for current file
        $filePath = $file->getRealPath();
        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Add current file to archive
        $zip->addFile($filePath, $relativePath);
    }
}
// Zip archive will be created only after closing object
$zip->close();
?>

This works fine with only one issue: if a folder does not have an image inside it, the folder is not backed up.

How can I tweak the code so that it zips up empty folders as well (so the exact structure matches what is online)?

=================== added

echo "<Br>". $filePath . "<br>".  $relativePath . "<br>".  $name ;

before last two }. This gives:

/home/fullpath/public_html/upload-here

/home/fullpath/public_html/upload-here/.
/home/fullpath/public_html

/home/fullpath/public_html/upload-here/..
/home/fullpath/public_html/upload-here/73
73
/home/fullpath/public_html/upload-here/73/.
/home/fullpath/public_html/upload-here

/home/fullpath/public_html/upload-here/73/..
/home/fullpath/public_html/upload-here/283
283
/home/fullpath/public_html/upload-here/283/.
/home/fullpath/public_html/upload-here

/home/fullpath/public_html/upload-here/283/..
/home/fullpath/public_html/upload-here/284
284
/home/fullpath/public_html/upload-here/284/.
/home/fullpath/public_html/upload-here

/home/fullpath/public_html/upload-here/284/..
/home/fullpath/public_html/upload-here/291
291
/home/fullpath/public_html/upload-here/291/.
/home/fullpath/public_html/upload-here

/home/fullpath/public_html/upload-here/291/..
/home/fullpath/public_html/upload-here/292
292
/home/fullpath/public_html/upload-here/292/.
/home/fullpath/public_html/upload-here

etc etc


Solution

  • Please try it. You can get the zip file including the empty folders.

    foreach ($files as $name => $file) {
    $filePath = $file->getRealPath();
    $relativePath = substr($filePath, strlen($rootPath) + 1);
    // Skip directories (they would be added automatically)
    if (!$file->isDir()) {
        // Add current file to archive
        $zip->addFile($filePath, $relativePath);
    } else {
        if($relativePath !== false)
            $zip->addEmptyDir($relativePath);
    }}