PHP 常用的函數(shù)之一就是下載文件功能的處理,這是非常有用的操作。無論是在系統(tǒng)設(shè)計中,還是在網(wǎng)站應(yīng)用開發(fā)中,下載文件都是一個經(jīng)常被用到的功能。比如在網(wǎng)站中提供給用戶下載未被壓縮的多個文件,或者是在備份文件過程中把一些數(shù)據(jù)文件下載到本地。
在PHP 中,下載文件的功能是通過設(shè)置 header 來實現(xiàn)的,并且 header 需要在所有輸出之前輸出。PHP 提供了一個非常方便的文件下載函數(shù),即:readfile(),它可以直接輸出文件內(nèi)容,可以用于輸出圖片、視頻等多種文件。
下面是一個簡單的例子,使用 readfile() 函數(shù)下載文件:
在這個例子中,首先需要定義 $file_url 變量,指定要下載的文件,然后設(shè)置 header 的內(nèi)容,包括指定 Content-Type,Content-disposition,Content-Transfer-Encoding 參數(shù)。最后調(diào)用 readfile 函數(shù)輸出文件內(nèi)容。
通常來說,我們需要做一些額外的處理,比如 檢查文件是否存在、設(shè)置下載速度、即使下載的文件較大,也能夠支持?jǐn)帱c續(xù)傳等等。下面我們來創(chuàng)建一個帶有以下功能的文件下載函數(shù):
- 檢查文件是否存在
- 輸出文件下載速度
- 支持?jǐn)帱c續(xù)傳
在這個函數(shù)中,我們先檢查文件是否存在。接著,我們引入了以下在設(shè)置下載速度與斷點續(xù)傳方面非常有用的方法。在設(shè)置下載速度時,我們直接使用了 usleep() 函數(shù),這個函數(shù)可以實現(xiàn)微秒級別的暫停,控制下載速度,讓它成為一個帶寬測試的理想場所。
這個函數(shù)會自動檢查來自客戶端帶上的 HTTP_RANGE 是否有值,表示是否支持?jǐn)帱c續(xù)傳。如果有,將按照客戶端分塊下載的需要發(fā)送帶 206 返回報頭。如果沒有,將按照原來的方式輸出整個文件。
總結(jié):下載文件是涉及到成千上萬的網(wǎng)站和系統(tǒng)的重要功能之一,這篇文章講述了在PHP中實現(xiàn)下載文件的方法。對于一個PHP開發(fā)者來說,這篇文章所介紹的知識是非常有用的。
在PHP 中,下載文件的功能是通過設(shè)置 header 來實現(xiàn)的,并且 header 需要在所有輸出之前輸出。PHP 提供了一個非常方便的文件下載函數(shù),即:readfile(),它可以直接輸出文件內(nèi)容,可以用于輸出圖片、視頻等多種文件。
下面是一個簡單的例子,使用 readfile() 函數(shù)下載文件:
$file_url = 'https://www.example.com/file.pdf'; header('Content-Type: application/octet-stream'); header("Content-Transfer-Encoding: Binary"); header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\""); readfile($file_url);
在這個例子中,首先需要定義 $file_url 變量,指定要下載的文件,然后設(shè)置 header 的內(nèi)容,包括指定 Content-Type,Content-disposition,Content-Transfer-Encoding 參數(shù)。最后調(diào)用 readfile 函數(shù)輸出文件內(nèi)容。
通常來說,我們需要做一些額外的處理,比如 檢查文件是否存在、設(shè)置下載速度、即使下載的文件較大,也能夠支持?jǐn)帱c續(xù)傳等等。下面我們來創(chuàng)建一個帶有以下功能的文件下載函數(shù):
- 檢查文件是否存在
- 輸出文件下載速度
- 支持?jǐn)帱c續(xù)傳
function download_file($file_path){ if(file_exists($file_path)){ //設(shè)置下載速度為200kb/s $fs=fopen($file_path,'rb'); $file_size=filesize($file_path); if ( isset($_SERVER['HTTP_RANGE']) && (preg_match('/^bytes=\d*-\d*(,\d*-\d*)*$/i',$_SERVER['HTTP_RANGE']) || $_SERVER['HTTP_RANGE']=='bytes=0-') ){ fseek($fs,0); list($verb,$ranges)=explode('=',$_SERVER['HTTP_RANGE']); header('HTTP/1.1 206 Partial Content'); header('Content-Type: '.mime_content_type($file_path)); header('Content-Length: '.($file_size - 1)); header(sprintf('Content-Range: bytes %s-%s/%s',0,min($file_size - 1,max(0,$ranges)),$file_size)); header('Accept-Ranges: bytes'); $length=max(0,min($file_size - 1,max(0,$ranges)) - 0); if ($length>0) { fseek($fs,0); } $part_size=1024*8; while ($length>0) { $conlen=min($length,$part_size); $length-=$conlen; echo fread($fs,$conlen); sleep(1); //睡眠1秒,下載速度200kb/s } } else{ header('Content-Type: application/octet-stream'); header("Content-disposition: attachment; filename=\"".basename($file_path)."\""); header('Content-Length: '.$file_size); $limit_rate = 200 * 1024; //定義下載速度為 200kb/s set_time_limit(0); //保證在下載大文件時將超時時間設(shè)置為無限大 fclose($fs); $fs = fopen($file_path, 'rb'); $bytes_send = 0; while (!feof($fs) && !connection_aborted() && $bytes_send<$file_size){ $buffer = fread($fs, 4096); $bytes_send += strlen($buffer); print($buffer); usleep(1000000/$limit_rate); } } } else{ header("HTTP/1.1 404 Not Found"); exit; } }
在這個函數(shù)中,我們先檢查文件是否存在。接著,我們引入了以下在設(shè)置下載速度與斷點續(xù)傳方面非常有用的方法。在設(shè)置下載速度時,我們直接使用了 usleep() 函數(shù),這個函數(shù)可以實現(xiàn)微秒級別的暫停,控制下載速度,讓它成為一個帶寬測試的理想場所。
這個函數(shù)會自動檢查來自客戶端帶上的 HTTP_RANGE 是否有值,表示是否支持?jǐn)帱c續(xù)傳。如果有,將按照客戶端分塊下載的需要發(fā)送帶 206 返回報頭。如果沒有,將按照原來的方式輸出整個文件。
總結(jié):下載文件是涉及到成千上萬的網(wǎng)站和系統(tǒng)的重要功能之一,這篇文章講述了在PHP中實現(xiàn)下載文件的方法。對于一個PHP開發(fā)者來說,這篇文章所介紹的知識是非常有用的。
上一篇php 不可見字符串
下一篇php 與 xml