【问题标题】:PHP: How to start serving a file that is being written, before it is completely written?PHP:如何在完全写入之前开始提供正在写入的文件?
【发布时间】:2021-10-28 12:15:27
【问题描述】:

我想通过 PHP “管道”一个文件。

我的 PHP 脚本通过“shell_exec”调用 bash 脚本。 bash 脚本下载文件并打印其数据。然后 PHP 脚本继续发送文件作为响应:

if (!file_exists("./$filename")) shell_exec("./get-file $file_id \"$filename\"");

if (file_exists($filename)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($filename));
    readfile($filename);
    unlink($filename);
    exit;
}

这工作正常。但是有没有办法在下载文件时“管道”文件?假设文件是​​ 500MB,而不是等待文件在服务器中下载,然后将其提供给客户端,有没有办法在下载内容时发送内容?原因很明显;我想尽量减少完成整个过程所需的总时间。如果我的要求是可能的,它可以使总时间减半。谢谢。

编辑:我找到了this,但解决方案是基于 curl 的。就我而言,该文件是由外部脚本下载的。所以我想运行一个循环,在这个循环中 PHP 脚本检查文件中是否写入了新字节,然后继续将它们发送到客户端,而不关闭连接。请注意,该文件不是基于文本的,它是一个音频文件。

编辑:现在我更接近了:我修改了外部脚本以在标准输出中输出文件,有效地将其数据提供给 shell_exec。现在,如何在 shell_exec 完成之前发送数据?我想我将不得不使用类似 ob_flush() 的东西,但我们将不胜感激。再次感谢

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
// This sends the data AFTER the exec finishes. I want to send them as they arrive, real-time
echo shell_exec("get-file $file_id");
die();

【问题讨论】:

标签: php file download


【解决方案1】:

好的,我在其他帖子中找到了答案。

我只是使用 passthru() 而不是 shell_exec(),它似乎工作得很好。

谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-30
    • 2012-06-14
    相关资源
    最近更新 更多