我已經寫了一個PHP頁面用於從服務器下載文件。該文件的名稱爲URL中的GET變量傳遞,然後將下面的代碼提供了下載的文件:使用PHP下載2GB文件
$filepath = "/path/to/files";
$filename = $_GET['id'];
if(! file_exists($filepath . "/" . $filename))
{
header("HTTP/1.1 404 Not Found");
@session_destroy();
exit(0);
}
$cmd = '/usr/bin/stat -c "%s" ' . $filepath . "/" . $filename;
$out = array();
$ret = 0;
exec($cmd, $out, $ret);
header('Content-type: application/octet-stream');
header('Content-Length: ' . $out[0]);
header('Content-Disposition: attachment; filename="' . $filename . '"');
readfile($filepath . "/" . $filename);
注意:我使用exec()調用,因爲大多數文件都大(> 2GB),較大的文件導致filesize()和stat()函數失敗。
無論如何,這段代碼幾乎適用於所有的文件。但是,如果文件大小爲,大小爲,大小爲2 GB(2147483648字節),則不會發送頭文件,瀏覽器會嘗試下載PHP頁面,導致保存一個空文件,稱爲download.php。
這裏的時候我測試了,捲曲發生了什麼事:
測試#1:獲得1 GB的文件名爲bigfile1:
$ curl -v http://<SERVER>/download.php?id=bigfile1
* About to connect() to <SERVER> port 80 (#0)
* Trying <IP_ADDRESS>... connected
* Connected to <SERVER> (<IP_ADDRESS>) port 80 (#0)
> GET /download.php?id=bigfile1 HTTP/1.1
> User-Agent: curl/7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.8 libssh2/0.18
> Host: <SERVER>
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 21 Jun 2011 19:10:06 GMT
< Server: Apache/2.2.4 (Unix) mod_ssl/2.2.4 OpenSSL/0.9.8c PHP/5.3.0
< X-Powered-By: PHP/5.3.0
< Set-Cookie: PHPSESSID=382769731f5e3782e3c1e3e14fc8ae71; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
< Pragma: no-cache
< Content-Length: 1073741824
< Content-Disposition: attachment; filename="bigfile1"
< Content-Type: application/octet-stream
<
* Connection #0 to host <SERVER> left intact
* Closing connection #0
測試#2:獲得2 GB的文件名爲bigfile2
$ curl -v http://<SERVER>/download.php?id=bigfile2
* About to connect() to <SERVER> port 80 (#0)
* Trying <IP_ADDRESS>... connected
* Connected to <SERVER> (<IP_ADDRESS>) port 80 (#0)
> GET /download.php?id=bigfile2 HTTP/1.1
> User-Agent: curl/7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.8 libssh2/0.18
> Host: <SERVER>
> Accept: */*
>
* Empty reply from server
* Connection #0 to host <SERVER> left intact
curl: (52) Empty reply from server
* Closing connection #0
我已經創建了大小爲1 GB,2 GB,3 GB,4 GB和5 GB的測試文件。 2 GB文件是唯一導致此行爲的文件,但它始終如一地發生,並且無論客戶端瀏覽器或操作系統如何,它都會發生。該服務器運行Debian GNU/Linux 4.0,Apache 2.2.4和PHP 5.3.0。
任何想法將不勝感激。謝謝!
它是導致問題的'readfile'或'exec'嗎?逐個評論它們以檢查。 – Matthew
什麼是您的'PHP_INT_MAX'輸出?和/或,這是一個64位或32位主機(操作系統類型是不相關的,我的意思是這裏的實際硬件類型)? –
每隔一行調用一次'error_log()'來找出2G文件的代碼路徑。難道只是該文件不存在並且你的腳本在'session_destroy()'之後退出? – Robin