Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

PHP ZIP folder and subfolder, except 2 folders

jjdk

Coder
Hi.
I have this program code which takes a zip-backup of a folder and all subfolders.
I need help on how to ignore 2 subfolders.
Any suggestions?
PHP:
<?php

Class ZipArchiver {

    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);
        if($sourcePath == $dirName){
            self::dirToZip($sourcePath, $z, 0);
        }else{
            self::dirToZip($sourcePath, $z, strlen("$parentPath/"));
        }
        $z->close();
        
        return true;
    }
    
    private static function dirToZip($folder, &$zipFile, $exclusiveLength){
        $handle = opendir($folder);
        while(FALSE !== $f = readdir($handle)){
            // Check for local/parent path or zipping file itself and skip
            if($f != '.' && $f != '..' && $f != basename(__FILE__)){
                $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::dirToZip($filePath, $zipFile, $exclusiveLength);
                }
            }
        }
        closedir($handle);
    }
    
}
    
$zipper = new ZipArchiver;

// Path of the directory to be zipped
$dirPath = dirname(__FILE__);

// Path of output zip file
$zipPath = 'backup-'.date('Y-m-d-His').'.zip';

// Create zip archive
$zip = $zipper->zipDir($dirPath, $zipPath);

if($zip){
    echo 'ZIP archive created successfully.';
}else{
    echo 'Failed to create ZIP.';
}

?>
 
I think it should be doable with pretty minor adjustments.

Since i am using my work computer, i cant test the code but here is the idea how you can achieve your goal. Minor bugs and typos propably, but you can figure em out.

PHP:
<?php

class ZipArchiver {

    public static function zipDir($sourcePath, $outZipPath, $excludeFolders = []) {
        // rest of your class here

        private static function dirToZip($folder, &$zipFile, $exclusiveLength, $excludeFolders = []) {
            $handle = opendir($folder);
            while (false !== $f = readdir($handle)) {
                if ($f != '.' && $f != '..' && $f != basename(__FILE__)) {
                    $filePath = "$folder/$f";

                    // exlude folders check
                    if (is_dir($filePath) && in_array($f, $excludeFolders)) {
                        continue; // if one of the directories to skip, we skip
                    }
                    
                    // ... rest of zipping logig here

                }
            }
            closedir($handle);
        }
    }

    // ... rest of your code here

$excludeFolders = ['not_this_directory1', 'not_this_directory2', 'not_this_directory3']; // here the directories you do NOT want to be archive
$zip = $zipper->zipDir($dirPath, $zipPath, $excludeFolders);
 
Thank you very much for your suggestion. 😀
I have now adjusted the program code.
I have specified 2 folders not to be included.
I have tried with:

1. $excludeFolders = ['backups', 'ckeditor'];
2. $excludeFolders = ['/backups', '/ckeditor'];
3. $excludeFolders = ['backups/', 'ckeditor/'];
4. $excludeFolders = ['/backups/', '/ckeditor/'];
5. $excludeFolders = [$dirPath.'/backups', $dirPath.'/ckeditor'];

But the 2 folders are still included in the zip file.

My code:
PHP:
<?php
Class ZipArchiver {
    
     public static function zipDir($sourcePath, $outZipPath, $excludeFolders = []) {
        $pathInfo = pathinfo($sourcePath);
        $parentPath = $pathInfo['dirname'];
        $dirName = $pathInfo['basename'];
    
        $z = new ZipArchive();
        $z->open($outZipPath, ZipArchive::CREATE);
        $z->addEmptyDir($dirName);
        if($sourcePath == $dirName){
            self::dirToZip($sourcePath, $z, 0);
        }else{
            self::dirToZip($sourcePath, $z, strlen("$parentPath/"));
        }
        $z->close();
        
        return true;
    }
    
    private static function dirToZip($folder, &$zipFile, $exclusiveLength, $excludeFolders = []) {
        $handle = opendir($folder);
        while (false !== $f = readdir($handle)) {
            if ($f != '.' && $f != '..' && $f != basename(__FILE__)) {
                $filePath = "$folder/$f";
                if (is_dir($filePath) && in_array($f, $excludeFolders)) {
                    continue; // if one of the directories to skip, we skip
                }
                // 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::dirToZip($filePath, $zipFile, $exclusiveLength);
                }
            }
        }
        closedir($handle);
    }
}

$zipper = new ZipArchiver;

// Path of the directory to be zipped
$dirPath = dirname(__FILE__); //in my example the path is /home/kalendersystem/public_html/demo

// Path of output zip file
$zipPath = 'Backup-'.date('Y-m-d-His').'.zip';

$excludeFolders = ['backups', 'ckeditor']; // in my example they are /home/kalendersystem/public_html/demo/backups/ and /home/kalendersystem/public_html/ckeditor/

// Create zip archive
$zip = $zipper->zipDir($dirPath, $zipPath, $excludeFolders);

if($zip){
    echo 'ZIP archive created successfully.';
}else{
    echo 'Failed to create ZIP.';
}

?>
 
By examining this part of code, you can figure out what is missing. It is a parameter that starts with "e" 😉


PHP:
        if($sourcePath == $dirName){
            self::dirToZip($sourcePath, $z, 0);
        }else{
            self::dirToZip($sourcePath, $z, strlen("$parentPath/"));
        }
 
BTW. I dont know which platform you are using or may it change in time. I would check does the dir path consist the name of folders you dont want to include instead of checking for excact match.

This ofcourse requires that your directories are named so that they cant cause human mistakes. "NOZIP_foldernamehere1", "NOZIP_foldernamehere2" etc.
 
By examining this part of code, you can figure out what is missing. It is a parameter that starts with "e" 😉


PHP:
        if($sourcePath == $dirName){
            self::dirToZip($sourcePath, $z, 0);
        }else{
            self::dirToZip($sourcePath, $z, strlen("$parentPath/"));
        }

Thanks for your tip. 😀 😀 😀 😀
Now it works.
Thank you very much - I'm so happy🙏😀
 

New Threads

Latest posts

Buy us a coffee!

Back
Top Bottom