Частичная отправка потока FTP на php://output

У меня есть 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-сервер, прежде чем он начнет загружаться на клиент.

Вопрос:

Как я могу начать потоковую передачу на php://output с FTP-сервера, как только первый $start байты были отброшены и прекратили потоковую передачу, когда я достиг байта $stop?

1 ответ

Решение

Вместо использования PHP- расширения FTP (например, ftp_get), можно открыть поток, используя встроенную в PHP оболочку FTP.

Следующий код транслирует части 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 работал нормально однако.

Другие вопросы по тегам