2014-01-08 56 views
1

我有一個PHP服務器,它通過從FTP服務器流式傳輸音頻文件,而不是公開提供。發送部分FTP流到php://輸出

發送選擇恰當的標題後,我只是文件流使用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和停止流時,我已經達到了「$一站式」字節?

+1

'ftp_nb_get()',它的最後一個參數'$ resumepos'和'ftp_nb_continue()'可能有用。 – user555

+0

@ user555我錯過了$ resumepos!是的,它肯定幫助我處理從哪裏開始。它不允許我下載一定數量的字節。 – ANisus

+0

在'while($ ret == FTP_MOREDATA)'循環中,您可能會以某種方式計算接收到的字節數,但PHP文檔沒有提及每個'ftp_nb_continue()'下載了多少字節。如果我必須通過查看FTP擴展[源代碼](https://github.com/php/php-src/blob/master/ext/ftp/ftp.c)來猜測,我會說'ftp_nb_continue() '下載'FTP_BUFSIZE'設置爲多少個字節,默認爲4096.對於完全控制,我認爲最好是在PHP中使用'REST'來指定你自己的FTP客戶端並計算接收到的字節數。 – user555

回答

1

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

下面的代碼將流的FTP文件的部分php://output

$start = 300; // First byte to stream 
$stop = 499; // Last byte to stream 
$url = "ftp://username:[email protected]/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可以正常工作。