PHP ZipArchive::addGlob()异常及增量更新归档文件的解决方法
解决PHP ZipArchive的两个常见问题:空压缩包与增量更新归档
问题1:压缩包为空,无法将文件放在归档顶层
你的代码中add_path设置为DIRECTORY_SEPARATOR是导致空包的核心原因——这个值会让文件被添加到一个以目录分隔符命名的无效虚拟路径下,而非归档的顶层目录。
要将CSV文件直接放在压缩包顶层,只需移除add_path参数,或者将其设为空字符串,同时保留remove_all_path => TRUE来剥离源文件的路径前缀:
修正后的代码:
$zip = new ZipArchive(); $open = $zip->open("$zipDirName/reports.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE); if ($open !== TRUE) throw new \Exception("CampaignsDeviceDays::saveCsvDaysDataZip() error. \$zip->open() failed with error code $open"); // 方案1:移除add_path参数,直接将文件放在顶层 $addGlob = $zip->addGlob("$tempDirName/*", GLOB_BRACE, ['remove_all_path' => TRUE]); // 或者方案2:显式将add_path设为空字符串 // $addGlob = $zip->addGlob("$tempDirName/*", GLOB_BRACE, ['add_path' => '', 'remove_all_path' => TRUE]);
这样所有CSV文件会直接出现在压缩包的根目录下,不会被嵌套到任何子文件夹中。
问题2:覆盖归档内指定文件,保留其他原有内容
使用ZipArchive::CREATE | ZipArchive::OVERWRITE会强制清空整个现有归档,不符合增量更新的需求。正确的做法是仅使用ZipArchive::CREATE标志打开归档:
- 如果归档文件不存在,
CREATE会创建新的归档; - 如果归档已存在,
CREATE会打开现有归档并保留其中的所有内容; - 当调用
addGlob或addFile添加同名文件时,ZipArchive会自动覆盖归档内已存在的对应文件,未被覆盖的原有文件会完整保留。
示例代码:
$zip = new ZipArchive(); // 仅使用CREATE标志,避免清空原有归档内容 $open = $zip->open("$zipDirName/reports.zip", ZipArchive::CREATE); if ($open !== TRUE) throw new \Exception("CampaignsDeviceDays::saveCsvDaysDataZip() error. \$zip->open() failed with error code $open"); // 添加文件:同名文件自动覆盖,其他原有文件保留 $addGlob = $zip->addGlob("$tempDirName/*", GLOB_BRACE, ['remove_all_path' => TRUE]); // 必须调用close(),确保所有修改写入磁盘 $zip->close();
内容的提问来源于stack exchange,提问作者Čamo
相关产品推荐
相关产品推荐

