Search code examples
phpzipcompressionprogress

PHP compress/zip files with percentage progress bar - is it possible?


Trying to compress bunch of files using ZipArchive class. All is working fine, but I would like to have some kind of status bar with percentage zipped while users are waiting for zipping to be completed.

Is this even possible with ZipArchive? Are there any other zib libraries I could use to accomplish this?

Thanks!


Solution

  • I was look for answer for extracting files which ZipArchive does not have a callback. The solution I found is looping over the files and creating them individually without using extractTo method. I am not sure if it is slower but in my case I have a small number of files and it is extremely fast (milliseconds).

    <?php
    $zip = new \ZipArchive();
    $res = $zip->open("PATH_TO_ZIP_FILE");
    
    $zip_files_length = $zip->numFiles;
    
    # Create progress logic here
    
    $extract_path = "PATH_TO_DIST";
    
    if ($res === true) {
        for ($index = 0; $index < $zip_files_length; $index++) {
            
            # Add progress advancement here
    
            // Get file path
            $stat      = $zip->statIndex($index);
            $file_name = $stat['name'];
            $dist      = "{$extract_path}/{$file_name}";
    
            // Check if the extracted file is a directory (ends with /)
            $is_dir = str_ends_with($file_name, '/');
    
            if ($is_dir) {
                // Create directory if it does not exist
                if (!is_dir($dist)) {
                    mkdir($dist, 0777, true);
                }
                continue;
            }
    
            // Create file parent directories if they do not exist
            $dir_name = dirname($dist);
            if (!is_dir($dir_name)) {
                mkdir($dir_name, 0777, true);
            }
    
            // Create file
            $content = $zip->getFromName($file_name);
            file_put_contents("{$extract_path}/{$file_name}", $content);
        }
    
        $zip->close();
    } else {
        throw new \Exception("Failed to extract {$PATH_TO_ZIP_FILE}");
    }
    
    # Add progress completion here