【问题标题】:Send partial of FTP stream to php://output将部分 FTP 流发送到 php://output
【发布时间】:2014-01-26 16:16:09
【问题描述】:

我有一个 PHP 服务器,它通过从不公开的 FTP 服务器流式传输音频文件来提供音频文件。

发送适当的标头后,我只需使用ftp_get 将文件流式传输到客户端,如下所示:

ftp_get($conn, 'php://output', $file, FTP_BINARY);

由于与Range 标头有关的原因,我现在必须提出只发送此流的一部分:

$start = 300; // First byte to stream
$stop = 499; // Last byte to stream (the Content-Length is then $stop-$start+1)

我可以通过将整个内容临时下载到文件/内存中来做到这一点,然后将所需的部分发送到输出。但是由于文件很大,该解决方案会导致客户端延迟,因为客户端必须等待文件首先下载到 PHP 服务器,然后才能开始下载到客户端。

问题:

如何在第一个 $start 字节被丢弃后立即从 FTP 服务器开始流式传输到 php://output 并在达到“$stop”字节时停止流式传输?

【问题讨论】:

  • ftp_nb_get(),它的最后一个参数$resumeposftp_nb_continue() 可能有用。
  • @user555 我错过了 $resumepos!是的,它肯定有助于我处理我的起点。它不允许我下载一定数量的字节。
  • while ($ret == FTP_MOREDATA) 循环中,也许您可​​以以某种方式计算接收到的字节数,但是PHP 文档没有提到每个ftp_nb_continue() 下载了多少字节。如果我必须通过查看 FTP 扩展 source code 来猜测,我会说 ftp_nb_continue() 下载的字节数与 FTP_BUFSIZE 设置的一样多,默认为 4096。为了完全控制,我认为最好自己扮演角色PHP 中的 FTP 客户端,使用 REST 并计算接收到的字节数。
  • @user555 我能够让它工作:)。你可以看到我的回答我是如何做到的。感谢您的建议!

标签: php ftp stream partial


【解决方案1】:

可以使用 PHP 的内置 FTP wrapper 打开流,而不是使用 PHP 的 FTP extension(例如 ftp_get)。

以下代码会将部分 FTP 文件流式传输到 php://output

$start = 300; // First byte to stream
$stop = 499; // Last byte to stream
$url = "ftp://username:password@server.com/path/file.mp3";

$ctx = stream_context_create(array('ftp' => array('resume_pos' => $start)));
$fin = fopen($url, 'r', false, $ctx);
$fout = fopen('php://output', 'w');

stream_copy_to_stream($fin, $fout, $stop-$start+1);

fclose($fin);
fclose($fout);

虽然stream_copy_to_stream 有一个$offset 参数,但使用它会导致错误,因为流不可搜索。但是,使用上下文选项 resume_pos 效果很好。

【讨论】:

    猜你喜欢
    • 2014-06-25
    • 1970-01-01
    • 2019-10-27
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2013-07-02
    • 1970-01-01
    相关资源
    最近更新 更多