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

PHP Gzip 壓縮輸出實戰:mod_deflate、ob_gzhandler 與效能驗證

     編輯:PHP 相關知識

核心原理:HTTP 內容編碼協商

  1. Client 請求頭:Accept-Encoding: gzip, deflate, br
  2. Server 檢查支援格式,選擇最高優先級(通常 gzip)
  3. Server 壓縮回應體,回應頭標記:Content-Encoding: gzip
  4. Client 自動解壓並渲染,過程對使用者透明

純文字內容(HTML/CSS/JS/JSON/XML)壓縮率通常 70%-90%,大幅降低頻寬與傳輸延遲。

方案一:Apache mod_deflate(推薦,全站生效)

模組載入確認

# Apache 2.4 通常內建
LoadModule deflate_module modules/mod_deflate.so
LoadModule filter_module modules/mod_filter.so  # 必須,mod_deflate 依賴

虛擬主機/目錄配置範例

<IfModule mod_deflate.c>
    # 核心開關
    SetOutputFilter DEFLATE
    
    # 指定壓縮 MIME 類型(避免圖片/二進位再壓縮)
    AddOutputFilterByType DEFLATE \
        text/html text/plain text/xml text/css \
        text/javascript application/javascript application/x-javascript \
        application/json application/xml application/rss+xml \
        application/x-font-ttf application/x-font-opentype \
        image/svg+xml
    
    # 排除已壓縮/二進位格式
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|ico|zip|gz|tgz|bz2|pdf|woff2?)$ no-gzip dont-vary
    
    # 代理快取友善
    Header append Vary User-Agent env=!dont-vary
    
    # 選擇性:壓縮等級 1-9 (預設 6)
    DeflateCompressionLevel 6
    
    # 選擇性:最小壓縮大小(位元組),避免微小檔案壓縮反增
    DeflateMinSize 512
</IfModule>

方案二:PHP ob_gzhandler(無需 Apache 模組)

三種啟用層級

範圍配置方式範例
全站php.inioutput_handler = ob_gzhandler
目錄/虛擬主機.htaccessphp_value output_handler ob_gzhandler
單一腳本代碼開頭ob_start('ob_gzhandler');

進階控制:條件式壓縮

<?php
// 僅當客戶端支援且非圖片請求時壓縮
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && 
    strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false &&
    !preg_match('/\.(gif|jpe?g|png|webp|ico|css|js)(\?.*)?$/', $_SERVER['REQUEST_URI'])) {
    ob_start('ob_gzhandler');
} else {
    ob_start();
}

// 你的 PHP 代碼...
echo $content;

ob_end_flush();
?>

方案三:應用層類庫(歷史參考)

早期 PHP 4 無 ob_gzhandler 時使用 class.gzip_encode.php,現已無需採用,略過。

驗證與除錯工具鏈

工具指令/操作預期結果
curlcurl -I -H "Accept-Encoding: gzip" https://example.com/回應頭含 Content-Encoding: gzip,Content-Length 明顯縮減
瀏覽器 DevToolsNetwork 標籤 → 檢查 Response Headers見 content-encoding: gzip,Size 顯示壓縮後/原始大小
線上測試https://www.giftofspeed.com/gzip-test/輸入 URL 即時分析壓縮率
Apache 日誌%{Content-Encoding}o 記錄壓縮狀態分析壓縮覆蓋率

常見問題與解決

  1. 壓縮後頁面亂碼/空白:
    • 確認 PHP 檔案編碼為 UTF-8 無 BOM。
    • 檢查是否重複壓縮(Apache + PHP 同時開啟),關閉其中一層。
    • 輸出前已有 ob_start() 且未 ob_end_clean(),導致巢狀緩衝衝突。
  2. IE 6/7 無法解壓:舊版 IE 對壓縮快取有缺陷,可針對 User-Agent 關閉壓縮:
    BrowserMatch ^Mozilla/4 gzip-only-text/html
  3. SSL/TLS 下壓縮風險 (BREACH/CRIME):敏感頁面(含 CSRF Token、個資)建議關閉壓縮或使用 Content-Security-Policy 降低風險。
  4. 動態內容壓縮 CPU 過高:調整 DeflateCompressionLevel 降至 1-3,或引入快取層減少動態生成頻率。

效能基準對比(典型 HTML 頁面 50KB)

指標無壓縮Gzip Level 6提升
傳輸大小50,000 bytes~12,000 bytes76% 減少
3G 網路傳輸時間~400ms~100ms75% 縮短
CPU 開銷 (單核)0~0.5ms可忽略
記憶體開銷0~2x 原始大小 (緩衝)~100KB

最佳實踐總結

  1. 優先使用 Apache mod_deflate,統一管理靜態/動態資源,效能最佳。
  2. PHP 層面用 ob_gzhandler 作為備援或針對性控制。
  3. 嚴格排除圖片、字型、壓縮檔等已壓縮 MIME 類型。
  4. 設定 Vary: Accept-Encoding 確保代理正確快取。
  5. 監控 mod_deflate 記憶體/CPU 使用,高併發時考慮 CDN 邊緣壓縮。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved