Windows Server下PHP7.4调用ZipArchive::close报创建临时文件未知错误
根本原因
- Windows默认Win32 API的路径最大长度为260字符,该长度包含完整路径末尾的空结束符,以及ZipArchive底层依赖的libzip库创建临时文件时追加的随机后缀、扩展名等开销。你观测到的250阈值,是因为libzip会在ZIP保存路径的同级目录生成临时文件,临时文件名会额外占用10字符左右的长度,260的总限制减去这部分开销就落到了250的触发阈值。
- PHP7.4对应的libzip版本低于1.7.0,默认不支持Windows的长路径特性,即使系统层面放开260字符限制,libzip也不会识别长路径前缀,依然会触发长度校验失败。
解决方案
方案1:适配长路径前缀(最优,无需调整业务逻辑)
- 首先开启Windows系统长路径支持:定位到注册表路径
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem,将LongPathsEnabled的DWORD值设置为1,重启服务器生效。 - 给ZIP保存路径增加Windows长路径识别前缀
\\?\,修改$zip->open相关代码即可:
$originZipPath = "/myfolder/myfile.zip"; $absoluteZipPath = realpath(dirname($originZipPath)) . DIRECTORY_SEPARATOR . basename($originZipPath); // 增加长路径前缀适配 $zipPath = "\\\\?\\" . $absoluteZipPath; $zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
该方案兼容PHP7.3及以上版本,适配后路径长度最大可支持32767字符。
方案2:调整临时文件目录
若无法修改系统注册表配置,可将PHP的临时目录sys_temp_dir修改为极短路径(如C:\zip_tmp),减少临时文件路径的总长度占用,避开260字符限制。
方案3:短路径生成后移动
若ZIP最终存储路径必须为长路径,可先将ZIP文件生成到短路径下(如C:\temp\temp.zip),打包完成后调用rename()函数移动到目标长路径位置,Windows原生文件移动API对长路径的兼容性优于libzip的临时文件逻辑。
内容的提问来源于stack exchange,提问作者Beauvais
相关产品推荐
相关产品推荐

