尝试使用 ZipArchive 类压缩一堆文件。一切工作正常,但我希望在用户等待压缩完成时有某种带有压缩百分比的状态栏。
这对于 ZipArchive 来说是可能的吗?我可以使用其他任何 zib 库来完成此任务吗?
谢谢!
将文件添加到 zip 中通常很快。如果您要压缩大量文件,通常最慢的过程是
$zip->close()
。 PHP zipArchive 类中有一个新方法:https://www.php.net/manual/en/ziparchive.registerprogresscallback.php
这将允许您监控拉链关闭的进度。
$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+ 对此进行了测试,但尚不可用。
请注意,谁来到这里希望找到一种方法来监视 extractTo 的进度:遗憾的是,这对 extractTo 不起作用,因为此方法不会在关闭时执行。
我正在寻找
extracting
文件的答案,其中 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