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

PHP 實作檔案下載限速:每秒 20.5KB 的流控範例

     編輯:PHP 綜合知識

應用場景

提供大型檔案下載時,避免單一連線佔滿頻寬,影響其他服務;或依方案等級限制免費用戶下載速度。

核心程式碼

<?php
$local_file = 'test-file.zip';        // 伺服器實體檔案
$download_file = 'your-download-name.zip'; // 使用者下載時的檔名
$download_rate = 20.5;                // 限速 KB/s

if (file_exists($local_file) && is_file($local_file)) {
    // 1. 發送下載 Header
    header('Cache-control: private');
    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($local_file));
    header('Content-Disposition: filename=' . $download_file);

    // 2. 立即刷新 Header
    flush();

    // 3. 開啟檔案流
    $fp = fopen($local_file, 'r');

    // 4. 分塊讀取、輸出、休眠
    while (!feof($fp)) {
        // 每次讀取 $download_rate KB
        echo fread($fp, round($download_rate * 1024));
        flush();      // 強制輸出到瀏覽器
        sleep(1);     // 暫停 1 秒
    }

    fclose($fp);
} else {
    die('Error: The file ' . $local_file . ' does not exist!');
}
?>

關鍵機制解析

  1. 分塊大小 = 速率 × 1024:20.5 * 1024 ≈ 21000 位元組,配合 sleep(1) 形成約 20.5 KB/s 平均速率。
  2. flush() 雙重保險:PHP 輸出緩衝 → Web Server 緩衝 → TCP 發送緩衝。flush() 推送至 Web Server,若啟用 output_buffering 需搭配 ob_flush()。
  3. Content-Length 必填:瀏覽器才能顯示進度條、支援斷點續傳(需額外處理 Range Header)。
  4. 記憶體恆定:僅在記憶體保留單一塊(~20KB),無論檔案多大均不會 OOM。

進階擴充:支援斷點續傳

// 解析 Range Header
$range = $_SERVER['HTTP_RANGE'] ?? '';
if ($range) {
    list(, $range) = explode('=', $range);
    list($start, $end) = explode('-', $range);
    $end = $end ?: filesize($local_file) - 1;
    header('HTTP/1.1 206 Partial Content');
    header('Content-Range: bytes ' . $start . '-' . $end . '/' . filesize($local_file));
    header('Content-Length: ' . ($end - $start + 1));
    fseek($fp, $start);
    // 迴圈中 fread 長度改為 min($chunk, $end - $pos + 1)
}

生產環境注意事項

  • Nginx/Apache 緩衝:若前端啟用 proxy_buffering 或 mod_deflate,flush() 可能不生效,需關閉或調整緩衝參數。
  • 大檔案執行時間:set_time_limit(0) 防止腳本超時。
  • 併發連線數:每條連線佔用一個 PHP-FPM worker,高併發下需調整 pm.max_children 或改用 Nginx limit_rate 於 Web Server 層限速(效能更好)。
  • 安全性:嚴格驗證 $local_file 路徑,防止目錄遍歷攻擊(../etc/passwd)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved