LAMP:如何从远程 URL/文件创建 .Zip 并将其即时流式传输到客户端

Posted

技术标签:

【中文标题】LAMP:如何从远程 URL/文件创建 .Zip 并将其即时流式传输到客户端【英文标题】:LAMP: How to create .Zip from remote URLs/files and stream it to the client on the fly 【发布时间】:2017-03-12 11:29:35 【问题描述】:

使用 S3 等用于对象存储的外部服务,提供存储文件的自定义 zip 存档的老问题变得有点复杂。一种方法是让 Web 服务器将所有资源复制到临时本地文件中,将它们编译成 .zip,然后将 zip 文件返回给用户,但这很慢且占用大量资源。

这可以与solution for local files 类似吗?例如你能curl 文件,以流模式将它们通过管道传输到zip,然后即时发送给用户吗?

【问题讨论】:

【参考方案1】:

是的——您可以让zip一组fifos而不是一组文件进行操作。代码如下:

$sh = 'mkfifo a.jpg b.jpg ; '.                     // 1
  'curl -s some_service.com/a.jpg > a.jpg & ' .    // 2
  'curl -s some_service.com/b.jpg > b.jpg & ' .    // 
  'zip -FI - a.jpg b.jpg | cat > out.fifo';        // 3

// Open output fifo & curl-zip task pipe
posix_mkfifo('out.fifo', 0777);                    // 4
$pipe_output = popen('cat out.fifo', 'r');         //
$pipe_curlzip = popen($sh, 'r');                   //

它的工作原理如下:

    我们有两个远程文件:some_service.com/a.jpgsome_service.com/b.jpg – 我们为每个文件创建一个 fifo,每个 fifo 都具有我们希望它出现在我们的 zip 文件中的相应文件的名称。所以对于some_service.com/a.jpg,我们创建了一个名为a.jpg的先进先出。 启动两个curl 任务,将远程文件a.jpgb.jpg 输入到各自的fifo 中。这些 curl 任务将挂起,直到从它们的输出 fifo 中读取某些内容,因此我们在后台运行它们 (&)。 启动我们的zip 任务,将我们的两个fifos 作为输入。我们cat 将其流式输出到 第三个​​ fifo - out.fifo - 以允许我们的 php 进程将文件流式传输给用户。 开始吧。

然后只需阅读out.fifo 的内容并将其发送给用户即可:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="Download.zip"');

while (!feof($pipe_output)) 
    echo fread($pipe_output, 128);   // Your magic number here

【讨论】:

以上是关于LAMP:如何从远程 URL/文件创建 .Zip 并将其即时流式传输到客户端的主要内容,如果未能解决你的问题,请参考以下文章

从远程 url 播放音频文件时如何生成音频频谱?

Android Java - 如何从 URL 下载 zip 文件?

Git直接从原点导出

php curl get 下载远程zip文件保存在本地例子

从 URL 下载返回的 Zip 文件

PHPSpreadsheet - 如何从 PHPSpreadsheet 创建一个 zip 文件?