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

PHP 輸出緩衝區 完整指南:ob 系列函式、GZIP 壓縮、靜態快取與常見坑

     編輯:PHP 相關知識

輸出緩衝區 讓 PHP 腳本先將輸出存入記憶體,再一次性或分階段送給瀏覽器,解決「header 已送出無法 setcookie」、捕獲不可控函式輸出、頁面壓縮、靜態頁生成等需求。

核心原理

  • 開啟 ob_start() 後,echo/print 寫入 OB 緩衝區,header() 直接寫入 SAPI 緩衝區。
  • 腳本結束或呼叫 ob_end_flush() 時,OB 內容移至 SAPI 緩衝區,隨後送往瀏覽器。
  • 可多層巢狀 ob_start(),ob_get_level() 取得層數。

常用函式速查表

四大經典應用場景

1. 解決「Header already sent」

<?php
ob_start();
echo '頁面內容...';
header('Location: /login.php'); // 正常運作
ob_end_flush();
?>

2. 捕獲 phpinfo()、var_dump() 等無法直接賦值的輸出

<?php
ob_start();
phpinfo();
$info = ob_get_clean();
file_put_contents('phpinfo.html', $info);
?>

3. GZIP 壓縮輸出 (需 zlib)

<?php
// 簡單啟用
ob_start('ob_gzhandler');
// 或手動判斷瀏覽器支援
if (str_contains($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', 'gzip')) {
    ob_start('ob_gzhandler');
} else {
    ob_start();
}
?>

4. 靜態頁生成 / 全頁快取

<?php
ob_start();
// ... 複雜邏輯產生頁面 ...
$html = ob_get_contents();
file_put_contents('cache/page.html', $html);
ob_end_flush(); // 仍正常輸出給使用者
?>

⚠️ 常見坑與最佳實踐

  • 順序:ob_flush() → flush() (先刷 PHP 緩衝,再推 Web Server 緩衝)。
  • 預設緩衝:php.ini output_buffering=4096 導致小輸出不即時,長輪詢/串流需 ob_implicit_flush(true) 或手動 ob_flush/flush。
  • 記憶體:大頁面整頁緩衝會佔用大量記憶體,串流輸出改用 ob_flush/flush 分塊送出。
  • 錯誤處理:ob_end_clean() 在例外發生時清理殘留緩衝,避免雙重輸出。
  • 不要濫用:純 API 回傳 JSON 無需 OB,直接 header('Content-Type: application/json'); echo json_encode($data);。

php.ini 相關設定

函式行為回傳
ob_start(cb?)開啟緩衝,可指定回調處理內容bool
ob_get_contents()取得目前緩衝內容string
ob_get_clean()取得內容並關閉、丟棄緩衝string
ob_end_flush()輸出內容並關閉緩衝bool
ob_end_clean()丟棄內容並關閉緩衝bool
ob_flush()輸出內容但保持緩衝開啟bool
flush()將 SAPI/伺服器緩衝推送給瀏覽器void
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
指令說明
output_bufferingOn/大小:全域啟用 OB,數值為緩衝上限位元組
output_handler全域回調,如 mb_output_handler、ob_gzhandler
implicit_flushOff/On:等同 ob_implicit_flush()