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

PHP 開啟 GZIP 頁面壓縮的三種方案:ob_gzhandler、自定義回調、Nginx/Apache 層面最佳實踐

     編輯:PHP 綜合知識

為什麼要啟用 GZIP?

典型 HTML/CSS/JS/JSON 壓縮率 70%-90%,顯著減少傳輸體積、提升首屏加載速度、降低帶寬成本。

方案一:PHP 內置 ob_gzhandler(最簡單)

<?php
// 必須在任何輸出前調用
if (extension_loaded('zlib')) {
    ob_start('ob_gzhandler');
}
?>
<!DOCTYPE html>
<html><head><title>GZIP Test</title></head>
<body>
<?php for ($i=0; $i<1000; $i++) echo "Hello World! "; ?>
</body></html>
<?php
if (extension_loaded('zlib')) ob_end_flush();
?>

原理:自動檢測 Accept-Encoding: gzip,輸出時壓縮並發送 Content-Encoding: gzip。

方案二:自定義壓縮回調(完全控制)

<?php
ob_start(function ($buffer) {
    // 1. 已發送頭部則不再壓縮
    if (headers_sent()) return $buffer;
    
    // 2. 檢查客戶端支持
    if (!extension_loaded('zlib') || 
        !isset($_SERVER['HTTP_ACCEPT_ENCODING']) ||
        stripos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === false) {
        return $buffer;
    }
    
    // 3. 壓縮級別 1-9(6 平衡)
    $compressed = gzencode($buffer, 6);
    
    // 4. 發送必要頭部
    header('Content-Encoding: gzip');
    header('Vary: Accept-Encoding'); // 關鍵:告訴代理按 Accept-Encoding 緩存不同版本
    header('Content-Length: ' . strlen($compressed));
    
    return $compressed;
});

// 業務邏輯輸出...
echo "<h1>大內容頁面</h1>";
?>

方案三:Web 服務器層面壓縮(生產環境強烈推薦)

優勢:無 PHP 開銷、靜態資源同樣壓縮、配置集中、性能最優。

Nginx 配置

# http 或 server 塊
gzip on;
gzip_vary on;              # 必須:發送 Vary 頭
gzip_min_length 1024;      # 小於 1KB 不壓縮(得不償失)
gzip_comp_level 6;         // 1-9,6 推薦
gzip_types                 // 壓縮類型(默認僅 text/html)
    text/plain
    text/css
    application/json
    application/javascript
    text/xml
    application/xml
    application/xml+rss
    text/javascript
    image/svg+xml;
gzip_disable "msie6";      // 兼容 IE6

Apache 配置 (mod_deflate)

<IfModule mod_deflate.c>
    # 啟用壓縮
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE application/json application/javascript
    AddOutputFilterByType DEFLATE application/xml application/xml+rss
    
    # 排除已壓縮/二進制
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|ico|zip|gz|pdf)$ no-gzip
    
    # 瀏覽器兼容
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    
    # Vary 頭
    Header append Vary User-Agent env=!dont-vary
</IfModule>

方案對比與選型

維度PHP ob_gzhandlerPHP 自定義回調Nginx/Apache
配置複雜度極低中中(一次配置全站生效)
性能開銷PHP 進程 CPUPHP 進程 CPUWeb 服務器進程(通常更高效)
靜態文件壓縮❌❌✅ 自動
流式響應支持✅✅✅
調試靈活性低高中
推薦場景快速測試、共享主機無權限特殊邏輯控制(如條件壓縮)✅ 生產環境標配

驗證壓縮是否生效

  1. 瀏覽器 DevTools → Network → Response Headers:存在 Content-Encoding: gzip。
  2. 命令行:curl -H "Accept-Encoding: gzip" -I https://example.com/ 查看頭部。
  3. 在線工具:GZIP Test。

避坑提醒

  • 不要雙重壓縮:PHP 壓縮 + Nginx 再壓 = 損壞內容。二選一。
  • Vary: Accept-Encoding 必須發送,否則 CDN/代理可能將壓縮版服務給不支持的客戶端。
  • 圖片/視頻/字體/已壓縮格式 不要再壓縮(體積不減反增、CPU 浪費)。
  • 輸出緩衝嵌套時,ob_gzhandler 只在最外層生效。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved