ZipArchive::close(): 无法打开文件: 好的,但是哪个文件?

ZipArchive::close(): Can't open file: Okay, but which file?

提问人:Adam 提问时间:11/1/2023 最后编辑:Adam 更新时间:11/6/2023 访问量:77

问:

我在 PHP 8.2 上使用 ZipArchive

我正在尝试为一个正在运行的网站创建一个备份,该网站包含 10 GB 的内容(图像、发票等)。

压缩失败,并显示:

ZipArchive::close(): 无法打开文件: 没有这样的文件或目录

我的服务器上确实有 200 GB 的可用磁盘空间,所以我认为空间不是问题所在。我读到这个问题可能是因为一个临时文件被添加到 ZipArchive 中,并且在 zip->close() 上该文件已被删除。

由于我有大约 48606 个文件和目录,因此了解无法打开哪个文件或目录对我非常有帮助。如果我只压缩几个文件夹,压缩就可以了。

所以基本上,在下面的代码中,我怎么能找出导致失败的文件?$zip->close()

$zip = new ZipArchive();

$zipFileName = base_path('example.zip');

if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) {

    $fileToAdd = base_path('Text');
    file_put_contents($fileToAdd, 'This is some content for the Text file.');

    $zip->addFile($fileToAdd);

    unlink($fileToAdd);

    try{
        $zip->close();
    } catch (\Exception $exception){
        // How to get the missing file base_path('Text')
        // here?
    }
    return 'ZIP archive created successfully!';
}

return 'Failed to create ZIP archive';

关闭时来自 ZipArchive 的异常消息仅

“ZipArchive::close():无法打开文件:没有这样的文件或目录”

PHP 压缩

评论

0赞 Olivier 11/1/2023
您的网站是否创建了您的代码会尝试压缩的任何临时文件?
1赞 Olivier 11/1/2023
请注意,可能不支持大于 4GB 的存档(不确定在 PHP 8.2 上是否仍然如此)。条目数量也有限制(见)。ZipArchive
0赞 Mark Adler 11/2/2023
关闭()后取消链接()怎么样?实际上,在您成功关闭之后。在存档之前删除它似乎非常危险。此外,没有理由不能实现该模块来记录并将工作推迟到 close(),然后完成所有操作。由于您无法控制该模块的实现,因此在关闭之前取消链接是不正确的。
0赞 Adam 11/2/2023
@MarkAdler当然,我的例子可以通过移动 after 来立即修复。我只是试图证明我的问题。在我的应用程序的备份脚本中,我不会取消链接任何文件。但是文件在其他支线进程中被删除,我需要找出这些是哪些文件。拥有 50k 的文件和文件夹让我很难找出哪里出了问题。unlink()close()
0赞 Adam 11/2/2023
@MarkAdler不确定你所说的“也没有理由不能实现模块来记录并将工作推迟到 close(),然后完成所有工作。如果模块能够弄清楚它无法打开文件,我想知道为什么它不能告诉我哪个文件。

答:

-3赞 ABK Bhuiyan 11/1/2023 #1

若要找出导致失败的文件,可以使用以下代码:$zip->close()

$zip = new ZipArchive();

$zipFileName = base_path('example.zip');

if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) {
   $fileToAdd = base_path('Text');
   file_put_contents($fileToAdd, 'This is some content for the Text file.');

   $zip->addFile($fileToAdd);

   unlink($fileToAdd);

   try {
       $zip->close();
   } catch (\Exception $exception) {
       // Get the missing file name
       $missingFileName = $exception->getMessage();

       // Log the missing file name
       \Log::error('Missing file name: ' . $missingFileName);

       // Rethrow the exception
       throw $exception;
   }

   return 'ZIP archive created successfully!';
}

return 'Failed to create ZIP archive';

此代码会将缺少的文件名记录到 Laravel 日志文件中。然后,您可以查看日志文件以查看哪个文件导致了错误。

下面是一个日志条目的示例:

错误:缺少文件名:/var/www/html/example.com/public/Text This 日志条目告诉我们,当 ZipArchive 已关闭。

确定丢失的文件后,您可以尝试解决问题。例如,您可能需要在关闭文件之前将文件添加到 ZipArchive 中,或者如果文件不存在,则可能需要创建该文件。

在您的情况下,文件文本可能在关闭 ZipArchive 之前被删除。若要解决此问题,您可以尝试在关闭 ZipArchive 之前将文件移动到其他位置。

以下是如何移动文件的示例:

$oldFileName = base_path('Text');
$newFileName = base_path('Temp/Text');

rename($oldFileName, $newFileName);

$zip->addFile($newFileName);

unlink($newFileName);

$zip->close();

此代码会将文件 Text 移动到 Temp 目录,然后再将其添加到 ZipArchive。将文件添加到 ZipArchive 后,它将被移回其原始位置。

我希望这会有所帮助!

评论

0赞 Adam 11/1/2023
这是行不通的。异常消息只是“ZipArchive::close():无法打开文件:没有这样的文件或目录”
3赞 Olivier 11/1/2023
@Adam 这看起来像一个生成的答案。
0赞 brombeer 11/1/2023
"此代码会将缺少的文件名记录到 Laravel 日志文件“Laravel?
0赞 Adam 11/2/2023
@brombeer 也许他知道,因为我在剧本中使用了“base_path”,这是一个 laravel 助手