2016-11-22 83 views
4

我想在PHP中編寫一個腳本來下載一個大的zip文件(2,663,439,370字節),然後我遇到了一個有趣但令人沮喪的問題:腳本首先下載了2.147.483.647字節,然後繼續下載文件,而不是附加到字節數2.147.483.648,2.1447.483.649等等,它繼續追加字節到從字節號1開始的文件。如何在PHP中下載大於2Gb的文件?

因此,下載的文件是由:字節1,字節2, ...字節2.147.483.647,字節1,字節2 ...等等。

我注意到2.147.483.647是32字節系統可以存儲的最大整數值。但是,我的服務器是一個64字節的系統,可以存儲大於此值的值。爲了證明它,var_dump((int)2147483648)返回正確的整數。儘可能(從php.net通過複製粘貼拍攝)

header('Content-Description: File Transfer'); 
header('Content-Type: application/octet-stream'); 
header('Content-Disposition: attachment; filename="Certificat.zip"'); 
header('Expires: 0'); 
header('Cache-Control: must-revalidate'); 
header('Pragma: public'); 
header('Content-Length: ' . filesize($zipname));  

readfile($zipname); 

有沒有人遇到了這個問題

我的下載腳本是正確的?

+0

看起來像PHP有一些軟限制設置? –

+1

你的系統可能是64位的,但它聽起來像你的PHP當然不是。一個64位int在['9223372036854775807''](https://en.wikipedia.org/wiki/9223372036854775807) – MonkeyZeus

+1

不管怎樣,如果你有完整的服務器訪問權限,並且它是Apache,那麼請查看[mod_xsendfile]( http://www.apachelounge.com/download/) – MonkeyZeus

回答

0

我最終解決了這個問題,通過刪除readfile()函數並使用fopen()fread()自己輸出文件的內容。

但是,處理這樣的大文件時,readfile()'失敗的原因仍然是一個開放的主題(我已閱讀php.net上的文檔,我找不到有關此問題的任何註釋)。所以我還在等那位經驗豐富的程序員給我啓迪:)。

0

我不知道這是否會是你的情況有所幫助,但你應該刪除 header('Content-Length: ' . filesize($zipname)); 我沒有當我是從前進流加載此幾次後,瀏覽器將繼續加載,直到腳本停止與content.I響應我不確定它是否適用於這個大文件,它可能是php的限制。

+1

通過這樣做,它只能從瀏覽器隱藏文件大小,並且無法估計下載時間,但結果相同。 –

1

讀取5.6源代碼,readfile返回​​。 Here's the source reference

挖掘更多一些,它出現與長整型的定義是通常 4個字節,給我們的整數您的功能停止在簽署最大值這個宏的交易。我沒有深入挖掘這一點,這是我的假設,並且鑑於你所經歷的行爲,這對我來說已經足夠了(但對於那些更迂腐的人來說)。另一方面,我個人從來沒有使用過readfile,fopen/fread組合,在性能和內存使用方面總是被證明是更好的。由於您可以讀取塊,而不是吞噬2GB的龐然大物,所以在服務器資源上更簡單。