摘要:下載文件的方式得到文件路徑從得到文件路徑務(wù)必使用上面這種方法得到路徑,不能簡(jiǎn)單的字符串拼接得到路徑如果輸入的是就可以訪問(wèn)任何路徑設(shè)置信息描述頁(yè)面返回的結(jié)果返回內(nèi)容的類型,此處只知道是二進(jìn)制流。
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)任何路徑
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)單也更快速
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/21071.html
摘要:的包管理器是,用來(lái)瀏覽并搜索查看最新發(fā)行版下載。的包管理器是下一代的,使用編寫,以格式發(fā)布。二發(fā)布時(shí)間軸三安裝與使用安裝主要是安裝和這兩個(gè)包管理器,然后通過(guò)包管理器安裝其他。 PHP社區(qū)提供了幾個(gè)管理擴(kuò)展和包的工具包括Pecl、Pear、Pear2和Composer。在不了解的情況下去使用這些工具必然會(huì)出現(xiàn)困惑,所以下面就簡(jiǎn)單介紹下這幾個(gè)管理工具。 一、簡(jiǎn)介 下面簡(jiǎn)要介紹 Pear、P...
摘要:本文以當(dāng)前最新版本演示整個(gè)源碼安裝的流程。下載源碼包訪問(wèn)官網(wǎng)的源碼包下載地址。下載源碼有兩種方式服務(wù)器端使用命令直接下載。 本文以當(dāng)前最新版本 PHP 7.3.1 演示整個(gè)源碼安裝的流程。 下載 PHP 源碼包 訪問(wèn) PHP 官網(wǎng)的源碼包下載地址 http://php.net/downloads.php。 showImg(https://segmentfault.com/img/rem...
摘要:下環(huán)境的搭建初學(xué),環(huán)境配置各種蛋疼。安裝環(huán)境點(diǎn)開上面的下載鏈接,進(jìn)入下載頁(yè)面,建議下載線程安全版本的環(huán)境。在路徑下新建一個(gè)文件,內(nèi)容添加,然后在瀏覽器輸入,如果出現(xiàn)如圖頁(yè)面,則表示環(huán)境安裝成功。至此,本地環(huán)境的搭建就完成了。 windows下PHP環(huán)境的搭建 初學(xué)PHP,環(huán)境配置各種蛋疼。首先,我要表示對(duì)度娘搜索結(jié)果的失望,以及,墻實(shí)在是高,有三層樓那么高。如果可能的話盡可能上goog...
閱讀 2655·2021-11-23 09:51
閱讀 1644·2021-11-22 13:54
閱讀 2782·2021-11-18 10:02
閱讀 936·2021-08-16 10:57
閱讀 3554·2021-08-03 14:03
閱讀 1873·2019-08-30 15:54
閱讀 3527·2019-08-23 14:39
閱讀 598·2019-08-23 14:26