一、前言
在各種網(wǎng)站中,我們經(jīng)常會(huì)遇到一些需要文件下載的情境。比如,下載一些PDF文件、音樂(lè)、視頻等等。對(duì)于這些下載需求,網(wǎng)站經(jīng)常會(huì)設(shè)置為登錄用戶的專屬文件下載中心。但是,對(duì)于某些站點(diǎn)并不想要用戶注冊(cè)登錄,那么該如何才能實(shí)現(xiàn)游客的文件下載需求呢?這時(shí)候,我們能夠用到PHP的內(nèi)置方法來(lái)實(shí)現(xiàn)Guest下載功能。
二、PHP Guest下載信息獲取
Guest下載始終有一定的安全風(fēng)險(xiǎn),因此我們需要采取一些預(yù)防措施。比如,可以向PHP腳本提交SHA1哈希值或縮寫的文件名。我們可以準(zhǔn)備sha1碼數(shù)組來(lái)匹配傳遞給腳本的哈希值或縮寫,只有匹配成功才允許文件的下載。代碼實(shí)現(xiàn)如下:
$down_files = array( 'file1'=>'file1.pdf.sha1', 'file2'=>'file2.docx.sha1', 'file3'=>'file3.zip.sha1' ); $down_folder = './download/'; if(isset( $_GET['file']) && isset($down_files[$_GET['file']])){ $sha1_file = $down_folder.$down_files[$_GET['file']]; if( file_exists($sha1_file)){ $sha1_code = trim(file_get_contents($sha1_file)); if(isset($_GET['hash']) && strlen($_GET['hash']) == strlen($sha1_code)){ if($_GET['hash'] == $sha1_code){ $file = $down_folder.$_GET['file']; if(file_exists($file)){ header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.$_GET['file'].'"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: '.filesize($file)); readfile($file); exit(); } } } } }
我們使用$get[‘file’]變量給腳本提供了下載文件的名稱。此名稱將從預(yù)定的數(shù)組中檢索出文件名,并嘗試加載與文件關(guān)聯(lián)的SHA1哈希值(附加了“.sha1”的文件名)。如果文件存在,就檢查web用戶是否提供了一個(gè)有效的SHA1哈希值。如果是這樣,我們就可以認(rèn)為,用戶已經(jīng)獲得了正確的HASH值,其確實(shí)可以下載該文件。
三、PHP Guest下載文件
下載一個(gè)文件來(lái)說(shuō),這個(gè)過(guò)程實(shí)際上非常簡(jiǎn)單。從業(yè)務(wù)需求的角度看,應(yīng)該:
- 設(shè)置MIME類型并強(qiáng)制執(zhí)行文件下載
- 通過(guò)緩沖讀/寫文件
- 返回?cái)?shù)據(jù)流
我們將主要使用HTTP協(xié)議頭來(lái)指定內(nèi)容類型、內(nèi)容長(zhǎng)度和文件名等。當(dāng)然,也可以使用文件擴(kuò)展名自動(dòng)映射到MIME類型,通俗點(diǎn)說(shuō)就是瀏覽器知道這是文件類型并會(huì)彈出下載框。代碼實(shí)現(xiàn)如下:
header('Content-Type: application/octet-stream'); // 指定為二進(jìn)制流的內(nèi)容類型 header('Content-Disposition: attachment; filename="'.$_GET['file'].'"'); // 強(qiáng)制下載 header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: '.filesize($file)); // 文件大小 readfile($file); // 讀取文件內(nèi)容
你可以使用header()函數(shù)也指定更多的頭部信息,來(lái)提高代碼的安全性和可維護(hù)性。但是需要注意的一點(diǎn)是:header()函數(shù)必須放在所有其他輸出內(nèi)容的前面。
四、結(jié)語(yǔ)
通過(guò)本文對(duì)PHP Guest下載的講解,相信大家已經(jīng)對(duì)這個(gè)特性有了更好的理解和掌握。在實(shí)際的網(wǎng)站開發(fā)中,我們也能夠采用上述代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)單、高效的文件下載中心,讓游客順利地下載站點(diǎn)上的文件。