警告:ZipArchive::close():创建临时文件失败:未知错误

Warning: ZipArchive::close(): Failure to create temporary file: Unknown error

我在 PHP 中遇到一个奇怪的错误,我在其中遍历了很多目录并通过压缩文件夹来归档旧内容,然后删除文件夹及其所有文件。这在很大程度上工作正常,但对于一些条目,我收到此错误:

Warning: ZipArchive::close(): Failure to create temporary file: Unknown error in myfile.php on line 132

我有这个 PHP 代码,直接取自 但我插入了一个 exit() 以确保捕获错误:

// Get real path for our folder
$rootPath = realpath("/myfolder/pathX");

// Initialize archive object
$zip = new ZipArchive();
$zip->open("/myfolder/myfile.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);

// Create recursive directory iterator
/** @var SplFileInfo[] $files */
$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($rootPath),
    RecursiveIteratorIterator::LEAVES_ONLY
);

foreach ($files as $name => $file) {
    // Skip directories (they would be added automatically)
    if (!$file->isDir()) {
        // Get real and relative path for current file
        $filePath = $file->getRealPath();
        $relativePath = substr($filePath, strlen($rootPath) + 1);

        // Add current file to archive
        $zip->addFile($filePath, $relativePath);
    }
}

// Zip archive will be created only after closing object
if(!$zip->close()) {
    exit();
}

错误是在行132上触发的,也就是这一行,if(!$zip->close()) {

我没有文件夹或文件权限问题,因为文件夹和文件确实被删除了(另一个代码),但我无法弄清楚 ZIP 中的 Unknown error 是什么?

我在 Windows 服务器上使用 PHP 7.4。

###更新###

似乎是ZIP文件路径太长导致的未知错误,但我不明白为什么。如果$zip->open("/myfolder/myfile.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);中的路径长于或等于250个字符,那么就会出现这个错误!?

我能理解是否会有 256 或 260 个字符的限制,正如我所见,那里可能会有一些限制,但为什么是 250 个?

目前我正在研究是否可以通过使用 DOS 命令 SUBST 或通过注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices

进行本地 drive/folder 映射来减少路径长度

经过更多分析,我发现 Unknown error 是由于 ZIP 文件路径太长 - 它比 250 个字符长,这似乎是Windows 限制,尽管我看到此限制的数字在波动,从 247 到 260 不等。

我尝试过的一个可能的解决方案是在 DOS 命令中执行 SUBST 命令,它为长路径创建一个驱动器 - 就像这样 subst O: D:\very\long\..\path。这将提供一个 O:\,我可以在其中直接连接,但这仅适用于我的本地用户帐户,也不会在重新启动后继续存在。

我发现有效的解决方案是在注册表中向 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices 添加一个新的 REG_SZ。我添加了这个 REG_SZ (字符串):

O: => \DosDevices\D:\very\long...\path

重启 Windows 服务器 (2019) 后,我现在有了 O 盘,可以在 IIS 中使用(到那时 PHP),我的问题已经解决: -)