PHP ZipArchive生成压缩包7Zip解压结构异常问题求助
7Zip解压Windows服务器生成的Zip包出现目录结构异常问题
问题现象
- WinRAR解压任意服务器生成的Zip包,目录结构正常:
file |__test1 |__ test04.txt - 7Zip解压CentOS服务器生成的Zip包结构正常,但解压Windows服务器生成的包时,目录结构异常,文件脱离子目录:
file |__test1 |__test1.Test04.txt
相关PHP代码
主逻辑代码
if ($zip->open($filePath, \ZipArchive::CREATE) !== true) { throw new \RuntimeException('Cannot open ' . $filePath); } $this->addContent($zip, (Storage::path($rootFolder . '/' . $folderName))); $zip->close();
递归添加文件的方法
private function addContent(\ZipArchive $zip, string $path) { /** @var SplFileInfo[] $files */ $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, FilesystemIterator::FOLLOW_SYMLINKS ), RecursiveIteratorIterator::SELF_FIRST ); while ($iterator->valid()) { if (!$iterator->isDot()) { $filePath = $iterator->getPathName(); $relativePath = substr($filePath, strlen($path) + 1); if (!$iterator->isDir()) { $zip->addFile($filePath, $relativePath); } else { if ($relativePath !== false) { $zip->addEmptyDir($relativePath); } } } $iterator->next(); } }
已尝试操作
替换RecursiveIteratorIterator的SELF_FIRST常量,问题未解决。
可行解决方案
1. 统一Zip内部路径分隔符为正斜杠
Windows系统下getPathName()返回的路径使用反斜杠\,直接作为Zip内部路径会导致7Zip解析异常。修改相对路径的处理逻辑,将反斜杠替换为正斜杠:
$relativePath = substr($filePath, strlen($path) + 1); // 统一替换为Zip标准的正斜杠路径分隔符 $relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
2. 移除手动添加空目录的逻辑
ZipArchive::addFile()会自动创建所需的父目录,手动添加空目录可能与自动创建的目录产生冲突,导致7Zip解析错误。删除添加空目录的代码块:
// 注释或删除以下代码 /* } else { if ($relativePath !== false) { $zip->addEmptyDir($relativePath); } } */
3. 使用OVERWRITE模式创建Zip包
替换CREATE模式为OVERWRITE,避免文件残留或缓存导致的结构异常:
if ($zip->open($filePath, \ZipArchive::OVERWRITE) !== true) { throw new \RuntimeException('Cannot open ' . $filePath); }
内容的提问来源于stack exchange,提问作者Khang Nguyễn
相关产品推荐
相关产品推荐

