可以将 7-zip 的标准输出提供给 PHP 脚本吗?
Posted
技术标签:
【中文标题】可以将 7-zip 的标准输出提供给 PHP 脚本吗?【英文标题】:Possible to feed stdout of 7-zip to PHP script? 【发布时间】:2011-06-03 12:37:05 【问题描述】:我想使用 7-Zip 压缩目录,然后将其下载到网络浏览器。
但是,不是压缩到一个文件,而是让 php 将该文件的内容提供给浏览器......理想情况下,我希望 7-Zip 将新存档的内容写入标准输出 as正在创建存档...同时让 PHP 刷新其缓冲区并将数据发送到浏览器。
你看,我正在创建的存档非常大。从用户的角度来看,使用普通方法,当他们单击“下载”时,首先会创建存档并保存到一个文件中(可能需要大约 10 分钟),然后才可以下载 PHP 厌倦的文件.我想要做的是将归档和输出步骤合并到一个进程中。
有人对此有意见吗?
这是 SourceForge 上正在尝试做同样事情的其他人...
http://sourceforge.net/projects/p7zip/forums/forum/383043/topic/3828566
=======
感谢大家的帮助。我将关闭这个线程,因为我最近发现 *** 上已经存在关于这个主题的精彩讨论。见:
LAMP: How to create .Zip of large files for the user on the fly, without disk/CPU thrashing
=======
这是我采用的最终解决方案,它对我来说非常有效。请注意,我使用的是“InfoZip”程序,您几乎可以在任何平台上找到它。
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename="file.zip"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
passthru("zip -8 -q -r - ./some_directory | cat");
【问题讨论】:
尝试将存档设置为dev/stdout
? (假设是 linux)
7za 可执行文件是否将压缩数据发送到它的标准输出?你需要先得到它。
执行以下操作:“7za a -lr -mx0 -so ./davedir/”会导致:“错误:我不会将压缩数据写入终端。”
那是因为您没有将结果传送到任何地方。不过,它有 -so 选项是有原因的。它足够聪明,不会把它吐出来并用垃圾填满你的屏幕。 php 中的 passthru 函数应该将标准输出从 7z 传输出去并允许它运行。值得一试。
On-the-fly zipping & streaming of large files, in PHP or otherwise的可能重复
【参考方案1】:
您可以尝试使用带有 -so(将数据写入标准输出)选项的 passthru 运行 7z。
只要您发送 7zip mime 类型的下载标头和内容类型标头,我相信它会起作用。
例子
<?php
$filename = "somefile.7z";
$contentType = "application/x-7z-compressed";
header("Content-type: ".$contentType); // tell the browser your sending a 7zip file
header("Content-Disposition: attachment; filename=\"".$filename."\""); // use 'attachment' to force a download
passthru('/path/to/7z a -so <fileOrDirToBe7Zipped>');
?>
希望有帮助!
【讨论】:
当我这样做时:“7za a -so ./davedir”... 我得到这个:“错误:我不会将压缩数据写入终端。”我可以期望这在从终端运行时不起作用,但在通过 PHP 的 passthru 函数时会成功吗? 在你的命令行上,如果你简单地尝试 "7za a -so './davedir' > davedir.7z 会发生什么 @tambler 你的权利,尽管有 -so 选项,7za 似乎没有输出到标准输出。呃……你有理由必须使用 7z,而不是其他压缩方法吗? 我刚刚发布了我开始使用的最终代码。到目前为止,它工作得很好。 我在 Linux 下尝试过 7z v9.20。它失败并出现以下错误:7z a -so / > /dev/null Creating archive stdout System error: E_NOTIMPL
【参考方案2】:
这是我采用的最终解决方案,它对我来说非常有效。请注意,我使用的是“InfoZip”程序,您几乎可以在任何平台上找到它。
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename="file.zip"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
passthru("zip -8 -q -r - ./some_directory | cat");
【讨论】:
【参考方案3】:这要么行不通,要么出现可怕的错误。网络实际上并不是这样工作的——许多浏览器将无法正确处理不完整的文件(这是他们将要得到的)。为什么不显示“正在生成您的文件!完成后我们将通过电子邮件将下载链接发送给您。”消息,或“请稍候,我们正在生成您的文件。这可能需要几分钟。”消息以及进度条?
【讨论】:
我只是想提出一个更优雅的解决方案,但如果这真的行不通,我们可能不得不这样做。 为什么不呢?此方法在生成页面时工作得很好,并且在工作时从 7zip 获取输出也应该工作。他不是在发送不完整的文件,而是在生成文件时发送它。当然,假设 7zip 从头到尾写入文件,我相信这是这里问题的一部分。请澄清。 是的。我的意图是让 7zip 压缩一个目录,并让 PHP 在生成数据时将其刷新到浏览器......从头到尾。 我可能是错的,但即使它有效,对用户来说也会是一种奇怪且不直观的体验——没有“进度”测量的下载持续 10 分钟或更长时间。我还希望某些浏览器会轮询文件的大小,并在达到该长度时停止,从而导致文件损坏/不完整。看起来你在这里设置了一个潜在的失败点而没有真正的收获。以上是关于可以将 7-zip 的标准输出提供给 PHP 脚本吗?的主要内容,如果未能解决你的问题,请参考以下文章