PHP has standard zip class “ZipArchive”. Zip files cab be created using that class, but when you need to add inner directories and files you need to use recursive approach. PHP provides RecursiveDirectoryIterator to recursively traverse directories and get inner directories and files.

We are going to use RecursiveDirectoryIterator to traverse whole directory recursively and adding it to zip.

function zipme($source, $destination)
{
    if (!file_exists($source)) {
        echo "source doesn't exist";
        return false;
    } 
    
    if (!extension_loaded('zip')) {
        echo "zip extension not loaded in php";
        return false;
    }
 
    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        echo "failed to create zip file on destination";
        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();
}

You can use that function like below

zipme('/path/to/directory/to/compress/', '/path/to/compressed.zip');
Advertisements