我試圖從一個外部API傳遞一個大文件給用戶,(認爲100MB或更多)如何直接開始下載遠程大文件?
目前,我正在使用一些偏執的腳本(由於過去的失敗)到儘快下載腳本。
通過「下載」,我只是指瀏覽器上的下載觸發器,而不是文件的實際下載。只需要用戶可以選擇他想要保存文件的位置即可。
set_time_limit(0);
apache_setenv('no-gzip', 1);
ini_set('zlib.output_compression', 0);
ini_set('output_buffering', 0);
ini_set('implicit_flush', 1);
for($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
ob_implicit_flush(1);
header('Content-Description: File Transfer');
header('Content-type: application/octet-stream');
header('Content-Transfer-Encoding: Binary');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Cache-Control: private');
ob_flush();
flush();
$fh = fopen($external_api_url, 'rb');
while(!feof($fh))
{
echo fread($fh, 512);
ob_flush();
flush();
}
fclose($fh);
使用此腳本,在下載彈出窗口出現之前,50mb文件仍然需要20秒,而更大的文件需要更長的時間。
有什麼方法可以更快地啓動流?
編輯: 我也嘗試了fpassthru()和readfile(),但是這些需要40秒鐘才能獲得相同的50mb文件,這讓我覺得這種方式更好。我也玩過不同的讀取大小(512,256,64,其他幾個),但我沒有注意到它們之間的差異)
如果你有PHP 5,你試過'$ contents = stream_get_contents($ fh); echo $ contents;'或'file_get_contents(...)'而不是'while'循環?此外,fread()實際上鼓勵您一次讀取8192個字節,因爲這是塊大小。 –
@Arthur Stream_get_contents和file_get_contents在發送給用戶之前是否會等待整個文件被下載到PHP中?此外,我不知道8192 bute chunk的大小,這可以解釋爲什麼我嘗試的不同值(全部在這個數字下)給出了相同的結果。有沒有辦法降低塊大小? – Johan