如何在 PHP 中创建适合 OS X 存档实用程序的流式 zip 存档?

发布于 2024-12-18 22:25:30 字数 3162 浏览 0 评论 0原文

我正在尝试为一个相对较小的 Web 应用程序集成一个按需备份系统,该系统允许用户下载服务器上所有文件的 zip 文件和数据库转储。 zip 文件以流式传输方式发送给用户,而不是作为一个整体打包到服务器上的临时目录中。

我使用名为 ZipStream 的第三方 PHP 类来完成此任务。该类托管在此处以及特定的类文件可以在此处查看。我选择了这个版本(有另一个较旧的版本),因为它支持包括目录。此外,该设置应该适用于无需通过 shell_exec()passthru() 访问 shell 命令的服务器。

我的简单测试设置正在运行,我可以使用控制台中的 unzip 命令或使用 The Unarchiver.app 提取生成的流式 zip。 OS X 的存档实用程序(Mac OS X 10.6 以及很可能较早和更高的版本)正在引起问题,因为它无法提取存档并出现以下错误:

Unable to unarchive "test.zip" into "test". (Error 1 - Operation not permitted.)

记录的实际错误是:

ditto: Couldn't read pkzip signature.

我找到了有关此问题的一些可能的解释, 此处StackOverflow 和我想修补 ZipStream 类以遵守 Zip 规范,以便 Archive Utility 能够按预期扩展存档。

ZipStream 类中的“需要提取的版本”(存储在 ATTR_VERSION_TO_EXTRACT 常量中)是:x0Ax00,但我不确定该表示法是否与上述问题中提到的标准 0x000A

该问题似乎与添加到 zip 文件中的目录有关。仅包含文本文件的 zip 文件不会导致使用存档实用程序出现问题。

由于这属于 PHP 领域的边缘,我不确定如何使用正确的十六进制字符串编辑脚本,或者如何将 Zend 解决方案适用于该特定脚本。

我在这里上传了生成的zip: http://dl.dropbox.com/u /6887873/test.zip

要生成的代码是示例代码的精简版本:

$extime = ini_get('max_execution_time');
ini_set('max_execution_time', 600);

include_once("ZipStream.php");

$fileTime = date("D, d M Y H:i:s T");

$chapter1 = "Chapter 1\n"
. "Lorem ipsum\n"
. "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec magna lorem, mattis sit amet porta vitae, consectetur ut eros. Nullam id mattis lacus. In eget neque magna, congue imperdiet nulla. Aenean erat lacus, imperdiet a adipiscing non, dignissim eget felis. Nulla facilisi. Vivamus sit amet lorem eget mauris dictum pharetra. In mauris nulla, placerat a accumsan ac, mollis sit amet ligula. Donec eget facilisis dui. Cras elit quam, imperdiet at malesuada vitae, luctus id orci. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque eu libero in leo ultrices tristique. Etiam quis ornare massa. Donec in velit leo. Sed eu ante tortor.\n";

$zip = new ZipStream("test.zip");

$zip->addFile("Hello World!\r\n", "Hello.txt");

$zip->addDirectory("files/");
$zip->addDirectoryContent("../images", "files/testing/");

$zip->finalize();

编辑:

我想我已经将问题范围缩小了一些。看起来十六进制字符串实际上并没有什么区别。使用 Archive Utility 扩展仅包含文本文件的生成 zip 时不会出现错误,因此在添加目录时似乎会发生损坏,特别是在调用 addDirectoryContent() 时,后者又调用 addLargeFile() ZipStream 类的。目录已正确添加,并且不会导致无效文件,一旦将 addDirectoryContent() 添加到混合中,存档实用程序就无法提取文件,并输出上述错误。

I'm trying to integrate an on-demand backup system for a relatively small web-application which allows the user to download a zip file of all the files on the server and a database dump. The zip file is streamed to the user, instead of packaged as a whole in a temporary directory on the server.

I'm using a third-party PHP class, called ZipStream, to accomplish this. The class is hosted here and the specific class file can be viewed here. I've chosen this version (there is another, older one) as it has support for including directories. Also, the setup should work on servers without access to shell commands via shell_exec() or passthru().

My simple test setup is working and I can extract the resulting streamed zip using the unzip command from the console or using The Unarchiver.app. OS X's Archive Utility (Mac OS X 10.6 and very likely older and later versions) is causing problems however as it fails to extract the archive with the following error:

Unable to unarchive "test.zip" into "test". (Error 1 - Operation not permitted.)

The actual error logged is:

ditto: Couldn't read pkzip signature.

I've found some possible explanations regarding this problem, here and here on StackOverflow and I would like to patch the ZipStream class to adhere to the Zip specification so that Archive Utility will expand the archive as expected.

The "Version needed to extract" (stored in the ATTR_VERSION_TO_EXTRACT constant) in the ZipStream class is: x0Ax00, but I'm not sure if that notation differs from the standard 0x000A mentioned in the aforementioned question.

The problem seems related to the directories added to the zip file. A zip file only containing a text file doesn't cause issues using Archive Utility.

As this moves alongside the fringes of the realm of PHP I'm not sure how to edit the script with the correct hex strings or how to appropriate the Zend solution to this specific script.

I've uploaded a generated zip here: http://dl.dropbox.com/u/6887873/test.zip

The code to generate is a trimmed down version of the example code:

$extime = ini_get('max_execution_time');
ini_set('max_execution_time', 600);

include_once("ZipStream.php");

$fileTime = date("D, d M Y H:i:s T");

$chapter1 = "Chapter 1\n"
. "Lorem ipsum\n"
. "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec magna lorem, mattis sit amet porta vitae, consectetur ut eros. Nullam id mattis lacus. In eget neque magna, congue imperdiet nulla. Aenean erat lacus, imperdiet a adipiscing non, dignissim eget felis. Nulla facilisi. Vivamus sit amet lorem eget mauris dictum pharetra. In mauris nulla, placerat a accumsan ac, mollis sit amet ligula. Donec eget facilisis dui. Cras elit quam, imperdiet at malesuada vitae, luctus id orci. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque eu libero in leo ultrices tristique. Etiam quis ornare massa. Donec in velit leo. Sed eu ante tortor.\n";

$zip = new ZipStream("test.zip");

$zip->addFile("Hello World!\r\n", "Hello.txt");

$zip->addDirectory("files/");
$zip->addDirectoryContent("../images", "files/testing/");

$zip->finalize();

EDIT:

I think I've narrowed the problem down a bit more. It doesn't seem the hex strings actually make a difference. An generated zip containing only a text file is expanded without errors using Archive Utility, so the corruption seems to occur when adding directories, specifically when calling addDirectoryContent(), which in turn calls addLargeFile() of the ZipStream class. Directories are added correctly and don't result in an invalid file, as soon as addDirectoryContent() is added to the mix Archive Utility fails to extract the files, outputting the errors above.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文