You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:40:26