PHP 的輸出緩衝區控制允許我們在腳本執行過程中暫存輸出內容,而非直接發送給瀏覽器。當啟用緩衝區時,所有 echo、print 等輸出語句的內容會先存放在內存緩衝區中;而 header()、setcookie()、session_start() 等發送 HTTP 標頭的函數則直接寫入程序緩衝區。腳本執行結束時,PHP 會自動將輸出緩衝區的內容刷新到程序緩衝區,最後統一發送給瀏覽器。
header()、setcookie()、session_start() 等函數。雖然可行,但建議養成良好編碼習慣,盡量避免依賴此特性。phpinfo() 會直接輸出大量 HTML,無法用變量接收。透過緩衡區即可捕獲其輸出。只需在 ob_start() 中指定回調函數 ob_gzhandler 即可實現頁面 GZIP 壓縮:
ob_start('ob_gzhandler');
// 你的頁面內容
注意事項:此方式需 PHP 安裝 zlib 擴展;且未自動判斷瀏覽器是否支援 GZIP(現代瀏覽器普遍支援,包含 iPhone Safari)。早期做法是手動檢測 $_SERVER['HTTP_ACCEPT_ENCODING'] 再決定是否壓縮。
| 函數 | 說明 |
|---|---|
ob_start() | 開啟輸出緩衝區,輸出不再直接發送瀏覽器,而是保存在緩衝區。 |
ob_clean() | 清空緩衝區內容,但不關閉緩衝區(不輸出)。 |
ob_end_clean() | 清空緩衝區並關閉緩衝區(不輸出)。 |
ob_get_clean() | 返回緩衝區內容並關閉緩衝區。等同於 ob_get_contents() + ob_end_clean()。 |
ob_flush() | 發送緩衝區內容到瀏覽器並清空緩衝區,但不關閉緩衝區。 |
ob_end_flush() | 發送緩衝區內容到瀏覽器、清空並關閉緩衝區。 |
ob_get_flush() | 返回緩衝區內容、關閉緩衝區並釋放內容。等同於 ob_end_flush() 並返回內容。 |
flush() | 將 PHP 緩衝區及 Web 服務器(如 Apache)緩衝區的內容全部推送給瀏覽器。 |
ob_get_contents() | 返回當前緩衝區內容,不輸出、不清空。 |
ob_get_length() | 返回緩衝區內容長度(位元組),未啟用時返回 FALSE。 |
ob_get_level() | 返回輸出緩衝機制的嵌套層級。 |
ob_get_status() | 獲取輸出緩衝區狀態信息陣列。 |
ob_implicit_flush() | 開啟/關閉絕對刷新。開啟後(true),每個輸出語句執行即直接發送瀏覽器,無需手動 flush()。 |
ob_gzhandler | ob_start 回調函數,用於 GZIP 壓縮緩衝區內容。 |
ob_list_handlers() | 列出正在使用的輸出處理器。 |
On 表示所有腳本啟用輸出控制;數值表示緩衝區最大位元組數,達上限自動刷新。mb_output_handler 進行編碼轉換)。ob_implicit_flush,預設 Off。echo 後使用 header() 重定向<?php
ob_start(); // 開啟緩衝區
echo "Hello\n"; // 輸出暫存
header("Location: index.php"); // 發送標頭,不報錯
ob_end_flush(); // 輸出全部內容到瀏覽器
?>
原理:開啟緩衝區後,echo 內容留在服務端,未送達瀏覽器,故標頭發送不衝突。
phpinfo() 輸出並存檔<?php
ob_start();
phpinfo();
$info = ob_get_contents(); // 獲取緩衝區內容
$file = fopen('info.txt', 'w');
fwrite($file, $info);
fclose($file);
?>
<?php
ob_start();
// 整頁 PHP 輸出邏輯
$content = ob_get_contents();
$fp = fopen("output00001.html", "w");
fwrite($fp, $content);
fclose($fp);
?>
適用於內容更新頻率低、流量大的頁面(如門戶網站首頁),可大幅降低資料庫與 PHP 解析壓力。
ob_gzhandler 進階配置可在 php.ini 全域啟用:
output_handler = ob_gzhandler
或透過 .htaccess(Apache):
php_value output_handler ob_gzhandler
或在代碼中單獨啟用:ob_start("ob_gzhandler");
避坑指南:Netscape 系列瀏覽器對壓縮圖片支援不佳,建議僅壓縮文本類資源(HTML、CSS、JS),對 JPEG/GIF 等圖片禁用壓縮,並針對不同瀏覽器測試。
flush() 生效:部分 Web 服務器預設 output_buffering=4096,需先填充足夠內容觸發刷新。常用技巧:print str_repeat(' ', 4096); 在 ob_flush() 前執行。ob_flush() 與 flush():
ob_flush():釋放 PHP 內部緩衝區內容到 Web 服務器緩衝區。flush():將 Web 服務器緩衝區內容推送給瀏覽器。ob_flush(),再 flush()。ob_start() 後,腳本執行完畢會自動刷新緩衝區並輸出,內容不會永遠留在緩衝區。