使用S3等外部服务进行对象存储,提供存储文件的自定义zip存档的老问题变得有点复杂。一种方法是让Web服务器将所有资源复制到临时本地文件,将它们编译成.zip,然后将zip返回给用户,但这很慢且资源密集。
这可以与solution for local files类似地完成吗?例如您可以curl
这些文件,在流媒体模式下将它们导入zip
,然后直接发送给用户吗?
答案 0 :(得分:0)
是的 - 您可以让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.jpg
和some_service.com/b.jpg
- 我们为每个创建一个fifo,每个fifo都有相应文件的名称,我们希望它出现在我们的zip文件中。因此,对于some_service.com/a.jpg
,我们创建了一个名为a.jpg
。curl
任务,将远程文件a.jpg
和b.jpg
提供给每个相应的fifo。这些curl任务将挂起,直到从输出fifos读取内容,因此我们在后台运行它们(&
)。zip
任务,给它两个十五作为输入。我们cat
将其流输出到 third 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
}