這是一個將檔案傳送給用戶端的函式 - 它看起來可能比需要的更複雜,但與較簡單的檔案傳送函式相比,它有許多優點
- 適用於大型檔案,每次傳輸僅使用 8KB 緩衝區。
- 如果用戶端斷線,則停止傳輸(不像許多腳本,會繼續讀取和緩衝整個檔案,浪費寶貴的資源),但不會停止腳本
- 如果傳輸完成,則返回 TRUE,如果在完成下載之前用戶端斷線,則返回 FALSE - 您通常需要這樣做,以便正確記錄下載。
- 傳送許多標頭,包括確保在任何瀏覽器/代理上最多快取 2 小時的標頭,以及大多數人似乎忘記的「Content-Length」。
(在 PHP4.3.x 下的 Linux (Apache) 和 Windows (IIS5/6) 上測試)
請注意,將提取受保護檔案的資料夾在此函式中設定為常數 (/protected) ... 現在以下是該函式
<?php
function send_file($name) {
ob_end_clean();
$path = "protected/".$name;
if (!is_file($path) || connection_status()!=0) return false;
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)(filesize($path)));
header("Content-Disposition: inline; filename=$name");
header("Content-Transfer-Encoding: binary\n");
if ($file = fopen($path, 'rb')) {
while(!feof($file) and (connection_status()==0)) {
print(fread($file, 1024*8));
flush();
}
fclose($file);
}
return (connection_status()==0) && !connection_aborted();
}
?>
以下是使用這個函式的範例:
<?php
if (!send_file("platinumdemo.zip")) {
die ("檔案傳輸失敗");
} else {
}
?>
此致,
Rasmus Schultz