在許多線上電影或許多軟體下載的網站,
都可以看到一個連結讓你點此下載,而無法讓你直接利用網址連接至被下載的檔案
這可以防止外站直接將檔案下載的連結連到你的站。
增加自己網站的負荷量卻沒增加人氣。
要達到這樣的功能,有幾種方式:
1. 利用php來存取控管檔案,所有的下載皆經過php檔案去處理。
2. 將檔案以BLOB的方式存進資料庫,以資料庫方式下載吐出檔案。
但是將檔案存進資料庫的話,在修改檔案內容、存取檔案上都將會較為不便
較為簡單的方式,是利用header去做檔案控制與下載的動作,
相關的詳細介紹可見: http://tw.php.net/header
下面的函數可以讓下載的檔案經由php處理再交由使用者下載,
我們可以將檔案放在伺服器主機上無法直接經由http存取的位置,
再利用php程式去存取本機電腦檔案。
這樣使用者便無法直接由網址來存取下載的檔案。
function dl_file($file){ //檢查檔案是否存在 if (!is_file($file)) { die("404 File not found!"); } //取得檔案相關資料 $len = filesize($file); $filename = basename($file); $file_extension = strtolower(substr(strrchr($filename,"."),1)); //將檔案格式設定為將要下載的檔案 switch( $file_extension ) { case "pdf": $ctype="application/pdf"; break; case "exe": $ctype="application/octet-stream"; break; case "zip": $ctype="application/zip"; break; case "doc": $ctype="application/msword"; break; case "xls": $ctype="application/vnd.ms-excel"; break; case "ppt": $ctype="application/vnd.ms-powerpoint"; break; case "gif": $ctype="image/gif"; break; case "png": $ctype="image/png"; break; case "jpeg": case "jpg": $ctype="image/jpg"; break; case "mp3": $ctype="audio/mpeg"; break; case "wav": $ctype="audio/x-wav"; break; case "mpeg": case "mpg": case "mpe": $ctype="video/mpeg"; break; case "mov": $ctype="video/quicktime"; break; case "avi": $ctype="video/x-msvideo"; break; //禁止下面幾種類型的檔案被下載 case "php": case "htm": case "html": case "txt": die("Cannot be used for ". $file_extension ." files!"); break; default: $ctype="application/force-download"; } //開始編寫header header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: public"); header("Content-Description: File Transfer"); //使用利用 switch判別的檔案類型 header("Content-Type: $ctype"); //執行下載動作 $header="Content-Disposition: attachment; filename=".$filename.";"; header($header ); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".$len); @readfile($file); exit; }
若您只是單純的要下載某個檔案,不需要用到上面那麼複雜的php類別,
可以直接使用下面的程式碼去下載檔案
$saveasname = "test.csv"; //要被儲存成的檔名 header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; Filename="'.$saveasname.'"');
上面的程式碼丟在 script 的前面送出 header 後
後面再將要存入的內容 echo 出來
瀏覽器自動會出現下載的功能…
如果想加快下載速度,可將Content-Encoding宣告為Gzip,
將檔案內容先壓縮過再提供給使用者下載,
這個非常適合用來做資料庫備份,
phpMyAdmin就是用這個方式來做資料庫備份的輸出輸入下載
檔案可以不用先存到伺服器端直接下載至客戶端,
增加執行的速度
/檔名 $saveasname = "test.txt.gz"; //Header設定 header('Content-Encoding:x-gzip'); header('Content-Type: application/x-gzip'); header('Content-Disposition: attachment; Filename="'.$saveasname.'"'); header('Pragma: no-cache'); //要輸出的內容用gzencode函式處理過 echo gzencode('hi', 9);
以下是關於GZIP的介紹
http://www.faqs.org/rfcs/rfc2616