在php进程之间的流中传递多个文件
Posted
技术标签:
【中文标题】在php进程之间的流中传递多个文件【英文标题】:Passing multiple files in a stream between php processes 【发布时间】:2017-04-06 21:29:35 【问题描述】:我需要能够让服务器 A 上的一个 php 用户进程通过 http:// 流从另一台服务器 B 请求数据,并且服务器 B 必须能够通过流返回多个文件。
然后,用户进程必须将其中一个文件发送到外部客户端,并将其他文件本地保存在服务器 A 上(稍后由客户端请求)。基本上,我发送一个带有图像文件的 svg 文件。
我想通过单流来做到这一点。我不想将任何东西保存到服务器 B 上的光盘上,并让用户一一请求。
这样做最干净的方法是什么? 谢谢!
【问题讨论】:
在您问题的当前措辞中,您说“将其他人保存在本地”,但同时也说“我不想将任何内容保存到光盘”。我不明白你想要“在本地保存其他人”是什么意思。 感谢您的评论。我澄清了这个问题。我可能会探索将所有文件发送给客户端的选项,但现在没有必要。 【参考方案1】:您可以根据需要向流中写入尽可能多的内容:挑战在于接收方(服务器 A 上的 PHP)必须能够识别每个下一个文件的开始位置。您可以自己为此考虑一些协议,例如将TLV 写入流或只是在每个文件的内容前面加上后面的文件内容字节数。请注意,使用此建议您将丢失文件名,因此您也需要合并这些文件名。但最好的方法可能是使用现有标准。在 linux 世界中,人们经常为此使用 TAR 或 TAR-GZ。您可以查看它或使用 ZIP 代替。 This question 包含一些关于如何做到这一点的选项。两个建议都使用库。
另一种选择是使用tempname
的临时文件:虽然它是文件,但您不必管理清理。如果服务器 B 配置为在内存中有 tempdir,则您满足您的要求:-)
Here is a similar question 关于使用 TAR-GZ。 this question 的第二个答案显示了如何通过命令行 tar
命令写入通过 PHP shell 执行从 PHP 调用的标准输出(具有不同级别的启用错误处理的各种选项)。
由于我是在手机上写的,所以我无法尝试提供示例。也许这个周末晚些时候我有时间编辑和添加工作代码来演示。如果你打败了我,请随意自己做:-)
【讨论】:
我将首先探索 ZipArchive 选项。编写协议只是系统可能崩溃的另一个地方。我什至可以考虑直接将存档传递给客户端并由 JS 处理。关于临时文件,我要避免的是服务器 A 独立请求每个文件。 “文件”根本就不是服务器 B 上的真正文件。它们只是刺痛或数据流。【参考方案2】:这是我根据 van Leeuwen 的一些建议所做的:
在服务器 B 端,我使用了 maennchen/ZipStream-PHP 组件,在代码的不同部分使用了诸如此类的调用:
$zipArchive = new ZipStream();
$zipArchive->addFile($file_name, $image->getImageBlob());
$zipArchive->addFile($this->getId().".svg", $svg);
$zipArchive->finish();
在服务器 B 端,我使用 ZipArchive() 类来处理接收到的文件。
由于两个不同但相互关联的原因,我对解决方案并不完全满意,我希望社区能帮助我改进:
-
ZipStream 组件将内容发送到输出缓冲区
直接,在每次 addFile 调用时,作为副作用。这违反了面向对象的好处
实践。最好使用任意流资源
可以由对象返回。
出于某种原因,ZipArchive 仅从文件系统加载文件。我必须将 zip 数据写入文件才能打开
使用 ZipArchive 对象,它可以工作,但是,比方说,在道德上
错了?!
这两个库都没有充分利用 PHP 强大的流功能。关于如何更好地做到这一点的任何想法?
【讨论】:
以上是关于在php进程之间的流中传递多个文件的主要内容,如果未能解决你的问题,请参考以下文章