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

Firefox「內容編碼錯誤」完整排查:ob_gzhandler、BOM、魔術引號與短標籤

     編輯:PHP 相關知識

Firefox 顯示「內容編碼錯誤,無法顯示您嘗試查看的頁面,因為它使用了無效或者不支援的壓縮格式」。此錯誤通常由 PHP 輸出壓縮、編碼衝突、輸出緩衝區管理不當引起。本文系統性整理 5 大成因與解決方案。

成因一:ob_gzhandler 壓縮衝突

現象

使用 ob_start('ob_gzhandler') 但伺服器不支援、或前已有輸出、或多次呼叫導致壓縮流損毀。

解決

<?php
// 方案 A:檢查支援度再啟用
if (extension_loaded('zlib') && !ini_get('zlib.output_compression')) {
    if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', 'gzip') !== false) {
        ob_start('ob_gzhandler');
    } else {
        ob_start();
    }
}

// 方案 B:最穩健 - 交給 PHP 內建 zlib 處理
if (extension_loaded('zlib')) {
    ini_set('zlib.output_compression', 'On');
    ini_set('zlib.output_compression_level', 3); // 1-9,3 平衡速度/壓縮率
}
// 以上放在所有輸出之前(最頂端)

成因二:ob_gzhandler + ob_clean() Bug

經典坑:啟用 ob_gzhandler 後呼叫 ob_clean() 或 ob_end_clean() 會導致後續輸出消失(瀏覽器收到空內容但實際已傳送)。

<?php
// 錯誤示範
ob_start('ob_gzhandler');
echo "content";
ob_clean(); // 或 ob_end_clean()
echo "more content"; // 瀏覽器不顯示,但 telnet 可見已傳送

// 正確做法:重新啟用壓縮
ob_start('ob_gzhandler');
echo "content";
ob_end_clean();
ob_start('ob_gzhandler'); // 必須重新啟用
echo "more content";

建議:避免在 ob_gzhandler 環境下使用 ob_clean/end_clean,改用 ob_start() 純緩衝不壓縮,或直接用 zlib.output_compression。

成因三:set_magic_quotes_runtime() 棄用錯誤

PHP 5.3+ 棄用,PHP 7.0+ 移除。錯誤訊息:Function set_magic_quotes_runtime() is deprecated

<?php
// 解決:註解或刪除該行
// set_magic_quotes_runtime(0);

// 或抑制錯誤(不推薦長期使用)
@set_magic_quotes_runtime(0);

成因四:短開啟標籤

PHP 5.3+ 預設 short_open_tag = Off,導致 直接輸出原始碼,破壞輸出流。

; php.ini
short_open_tag = On

; 或程式碼統一使用完整標籤
<?php echo $username; ?>

成因五:UTF-8 BOM (Byte Order Mark) 導致輸出提前

以記事本儲存 UTF-8 檔案會自動加入 BOM (EF BB BF),導致 header()、session_start()、ob_gzhandler 失效。

檢測與批量移除

<?php
// 檢測單一檔案
function has_bom($file) {
    $content = file_get_contents($file);
    return (substr($content, 0, 3) === "\xEF\xBB\xBF");
}

// 批量移除(放在專案根目錄執行)
$dir = __DIR__;
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($iterator as $file) {
    if ($file->isFile() && in_array($file->getExtension(), ['php','html','css','js','inc'])) {
        $content = file_get_contents($file->getPathname());
        if (substr($content, 0, 3) === "\xEF\xBB\xBF") {
            file_put_contents($file->getPathname(), substr($content, 3));
            echo "Removed BOM: " . $file->getPathname() . "\n";
        }
    }
}

完整除錯檢查清單

  1. [ ] 所有 PHP 檔案為 UTF-8 無 BOM 編碼
  2. [ ] 程式入口最頂端無任何空白、換行、HTML 輸出
  3. [ ] 僅使用 zlib.output_compression 或正確的 ob_gzhandler 模式
  4. [ ] 移除 set_magic_quotes_runtime() 呼叫
  5. [ ] 統一使用 標籤
  6. [ ] error_reporting(E_ALL); ini_set('display_errors', 1); 開發環境開啟
  7. [ ] 瀏覽器 Network 分頁檢查 Content-Encoding: gzip 與 Transfer-Encoding: chunked 是否正常
黃金法則:「輸出壓縮交給 PHP 內建 zlib.output_compression,應用層不要手動 ob_gzhandler,除非你完全理解輸出緩衝區機制。」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved