溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

php是如何下載文件的

發(fā)布時(shí)間:2020-08-28 14:28:54 來(lái)源:億速云 閱讀:170 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹php是如何下載文件的,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

php下載文件的方法:1、從“$_GET['file']”得到文件路徑;2、設(shè)置header信息;3、使用“file_get_contents()”和“file()”方法;4、通過(guò)“readfile”和“fopen”方法。

php是如何下載文件的

PHP下載文件的方式

1. 得到文件路徑

從$_GET['file']得到文件路徑

$path_parts = pathinfo($_GET['file']);
$file_name  = $path_parts['basename'];
$file_path  = '/mysecretpath/' . $file_name;

務(wù)必使用上面這種方法得到路徑,不能簡(jiǎn)單的字符串拼接得到路徑

$mypath = '/mysecretpath/' . $_GET['file'];

如果輸入的是../../,就可以訪問(wèn)任何路徑

2. 設(shè)置header信息

header('Content-Description: File Transfer'); //描述頁(yè)面返回的結(jié)果
header('Content-Type: application/octet-stream'); //返回內(nèi)容的類型,此處只知道是二進(jìn)制流。具體返回類型可參考http://tool.oschina.net/commons
header('Content-Disposition: attachment; filename='.basename($file));//可以讓瀏覽器彈出下載窗口
header('Content-Transfer-Encoding: binary');//內(nèi)容編碼方式,直接二進(jìn)制,不要gzip壓縮
header('Expires: 0');//過(guò)期時(shí)間
header('Cache-Control: must-revalidate');//緩存策略,強(qiáng)制頁(yè)面不緩存,作用與no-cache相同,但更嚴(yán)格,強(qiáng)制意味更明顯
header('Pragma: public');
header('Content-Length: ' . filesize($file));//文件大小,在文件超過(guò)2G的時(shí)候,filesize()返回的結(jié)果可能不正確

3. 輸出文件之file_get_contents()方法

file_get_contents()把文件內(nèi)容讀取到字符串,也就是要把文件讀到內(nèi)存中,再輸出內(nèi)容

$str = file_get_contents($file);
echo $str;

這種方式,只要文件稍微一大,就會(huì)超過(guò)內(nèi)存限制

4. 輸出文件之file()方法

與file_get_contents()差不多,只不過(guò)是file()會(huì)把內(nèi)容按行讀取到數(shù)組中,也是需要占用內(nèi)存

$f = file($file);
while(list($line, $cnt) = each($f)) {
   echo $cnt;
}

文件大的時(shí)候也會(huì)超出內(nèi)存限制

5. 輸出文件之readfile()方法

readfile()方法:讀入一個(gè)文件并寫入到輸出緩沖

這種方式可以直接輸出到緩沖,不會(huì)整個(gè)文件占用內(nèi)存

前提要先清空緩沖,先要讓用戶看到下載文件的對(duì)話框

while (ob_get_level()) ob_end_clean();
//設(shè)置完header以后
ob_clean();
flush();  //清空緩沖區(qū)
readfile($file);

這種方法可以輸出大文件,讀取單個(gè)文件不會(huì)超出內(nèi)存限制,但下面的情況除外。

readfile()在多人讀取文件的時(shí)候同樣會(huì)造成PHP內(nèi)存耗盡:http://stackoverflow.com/questions/6627952/why-does-readfile-exhaust-php-memory

PHP has to read the file and it writes to the output buffer. So, for 300Mb file, no matter what the implementation you wrote (by many small segments, or by 1 big chunk) PHP has to read through 300Mb of file eventually.

If multiple user has to download the file, there will be a problem. (In one server, hosting providers will limit memory given to each hosting user. With such limited memory, using buffer is not going to be a good idea. )

I think using the direct link to download a file is a much better approach for big files.

大意:PHP需要讀文件,再輸出到緩沖。對(duì)于一個(gè)300M的文件,PHP最終還是要讀300M內(nèi)存。因此在多個(gè)用戶同時(shí)下載的時(shí)候,緩沖也會(huì)耗盡內(nèi)存。(不對(duì)還請(qǐng)指正)

例如100個(gè)用戶在下載,就需要100*buffer_size大小的內(nèi)存

6. 輸出文件之fopen()方法

set_time_limit(0);
$file = @fopen($file_path,"rb");
while(!feof($file))
{
    print(@fread($file, 1024*8));
    ob_flush();
    flush();
}

fopen()可以讀入大文件,每次可以指定讀取一部分的內(nèi)容。在操作大文件的時(shí)候也很有用

7. 總結(jié)

利用PHP下載文件時(shí),應(yīng)該要注重場(chǎng)景。如果本身只是幾個(gè)小文件被下載,那么使用PHP下載比較好;但是如果PHP要承受大量下載請(qǐng)求,這時(shí)下載文件就不該交給PHP做。

對(duì)于Apache,有mod_xsendfile可以幫助完成下載任務(wù),更簡(jiǎn)單也更快速

以上是php是如何下載文件的的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI