能否在PHP中使用百分比进度条压缩/打包文件?

3

尝试使用ZipArchive类来压缩一堆文件。一切都正常工作,但我希望在用户等待压缩完成时有一种带有百分比压缩状态的状态栏。

使用ZipArchive能实现这个吗?还有其他的压缩库可以用来完成这个任务吗?

谢谢!


也许是ZipArchive类?我没有看到ZipLibrary。 - Mark Adler
对不起,是的,我正在使用ZipArchive。(http://php.net/manual/zh/class.ziparchive.php) - elveez
3个回答

3
通常将文件添加到zip中是很快的。如果您要压缩大量文件,则通常最慢的过程将是$zip->close()。PHP zipArchive类中有一种新方法:https://www.php.net/manual/en/ziparchive.registerprogresscallback.php,这将允许您监视zip关闭的进度。
$zip = new ZipArchive();

if ($zip->open('php.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
    $zip->addFile(PHP_BINARY, 'php');

    $zip->registerProgressCallback(0.05, function ($r) {
        printf("%d%%\n", $r * 100);
    });

    $zip->close();
}

这似乎在PHP 8.0中可用。我测试过PHP 7.4+,但尚未在那里提供。


2

如果你来到这里希望找到一种监测extractTo进度的方法,请注意:对于extractTo,这种方法不起作用,因为该方法在关闭时没有被执行。


1
我在寻找关于提取文件的答案,因为ZipArchive没有回调函数。我找到的解决方案是循环遍历文件,并逐个创建它们,而不使用extractTo方法。我不确定这样做是否会更慢,但在我的情况下,文件数量很少,速度非常快(毫秒级)。
<?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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接