首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 文件下載標準實現:Header 控制 + 分塊讀取 + 中文文件名支持

     編輯:PHP 相關知識

功能特性

  • 支持大文件分塊輸出,不佔用過多內存。
  • 自動處理中文文件名編碼轉換(UTF-8 → GB2312)。
  • 支持相對/絕對路徑,自動補全斜槓。
  • 完整的 HTTP 下載頭:Content-Disposition、Accept-Ranges、Content-Length。

完整函數

<?php
function downloadFile($FileName, $FilePath = '') {
    header("Content-type: text/html; charset=utf-8");
    if (strlen($FileName) <= 3) { exit("下載失敗:文件信息有誤"); }

    // 文件名編碼轉換,防止中文亂碼
    $FileName = iconv("utf-8", "gb2312", $FileName);

    // 路徑標準化
    if (!is_null($FilePath) && strlen($FilePath) > 1) {
        if (substr($FilePath, 0, 1) === '/') { // 絕對路徑(相對網站根目錄)
            $FilePath = $_SERVER['DOCUMENT_ROOT'] . $FilePath;
        }
        if (substr($FilePath, -1) !== '/') $FilePath .= '/';
        if (strpos($FilePath, ':') !== false) $FilePath = str_replace('/', '\\', $FilePath); // Windows 絕對路徑
    } elseif (strlen($FilePath) == 1 && $FilePath !== '/') {
        $FilePath .= '/';
    } else {
        $FilePath = '';
    }

    $fullPath = $FilePath . $FileName;
    if (!file_exists($fullPath)) { exit("下載失敗:文件未找到"); }

    $FileSize = filesize($fullPath);

    // 發送下載頭
    header("Content-type: application/octet-stream");
    header("Accept-Ranges: bytes");
    header("Content-Length: $FileSize");
    header("Content-Disposition: attachment; filename=\"$FileName\"");

    // 分塊輸出
    $fp = fopen($fullPath, 'rb');
    $buffer = 1024 * 512; // 512KB
    while (!feof($fp) && $FileSize > 0) {
        $read = min($buffer, $FileSize);
        echo fread($fp, $read);
        $FileSize -= $read;
        @ob_flush(); @flush();
    }
    fclose($fp);
    exit;
}

// 使用示例
// downloadFile('測試報告.pdf', '/uploads/2024/01/');
?>

關鍵點解析

  1. 二進制模式:fopen($path, 'rb') 確保跨平台正確讀取。
  2. 緩衝刷新:ob_flush() + flush() 實時推送數據到瀏覽器,大文件不卡死。
  3. 中文文件名:iconv('utf-8','gb2312') 兼容老版本 IE/Edge;現代瀏覽器支持 RFC 5987 編碼(filename*=UTF-8''...),可雙頭並發。
  4. 斷點續傳:已發送 Accept-Ranges: bytes,配合 $_SERVER['HTTP_RANGE'] 可實現斷點下載(本函數未實現,留作擴展)。

常見問題

  • 輸出前有空白字符 → 確保文件開頭無 BOM、無 echo/空行。
  • 內存耗盡 → 增加 memory_limit 或縮小緩衝區。
  • 權限不足 → 確保 PHP 進程對文件有讀權限。

總結

該下載函數結構清晰、健壯性強,適合直接集成到項目中。生產環境建議添加權限校驗、日誌記錄、限速控制等增強功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved