PHP 輸出控制函數 (Output Control Functions) 允許我們攔截、緩衝、操作腳本的輸出內容。這在「輸出內容後仍需發送 HTTP Header」、「頁面靜態化快取」、「錯誤頁面友善化」等場景極為關鍵。本文系統整理核心函數、運作機制與四大實戰案例。
| 函數 | 說明 |
|---|---|
ob_start([callback, chunk_size, flags]) | 開啟輸出緩衝,選擇性指定回呼函數處理緩衝內容 |
ob_get_contents() | 取得目前緩衝區內容 (字串) |
ob_get_clean() | 取得內容並關閉/清空緩衝區 |
ob_get_flush() | 取得內容、輸出至瀏覽器、關閉緩衝區 |
ob_end_clean() | 丟棄緩衝內容並關閉緩衝 |
ob_end_flush() | 輸出緩衝內容並關閉緩衝 |
ob_flush() | 刷新緩衝區 (送出至瀏覽器) 但保持開啟 |
ob_clean() | 清空緩衝區但保持開啟 |
ob_start() 後,所有非 Header 的輸出 (echo, print, HTML 區塊) 會被導向內部緩衝區。ob_gzhandler)。ob_end_flush() 時,緩衝內容才會真正送達瀏覽器。在輸出內容 之前 開啟緩衝,即可在任意位置呼叫 header()、setcookie()、session_start()。
<?php
ob_start(); // 必須在任何輸出前
echo 'Hello World'; // 此輸出被緩衝
header('Location: https://example.com'); // 正常運作
?>
ob_start();
// 大量運算、資料庫查詢、模板渲染...
$content = ob_get_contents();
ob_end_clean();
file_put_contents('cache/page.html', $content);
echo $content; // 直接輸出
ob_start();
phpinfo();
$info_html = ob_get_contents();
ob_end_clean();
// 現在 $info_html 可存入資料庫、發送 Email、或篩選敏感資訊後再輸出
echo $info_html;
function my_error_handler($errno, $errstr, $errfile, $errline) {
// 只處理非致命錯誤
if (!(error_reporting() & $errno)) return false;
$msg = "[$errno] $errstr in $errfile:$errline";
error_log($msg); // 寫入系統日誌
// 若在緩衝中,可直接輸出友善頁面
if (ob_get_level() > 0) {
ob_clean();
echo "系統暫時異常,請稍後再試
";
echo "錯誤代碼: $errno
";
ob_end_flush();
exit(1);
}
return true; // 讓內建處理器繼續
}
set_error_handler('my_error_handler');
ob_start(); // 開啟緩衡以便攔截
// ... 應用程式邏輯 ...
ob_end_flush();
function compress_html($buffer) {
// 移除註解
$buffer = preg_replace('/<!--.*?-->/s', '', $buffer);
// 壓縮空白
$buffer = preg_replace('/\s+/', ' ', $buffer);
return $buffer;
}
ob_start('compress_html');
// 輸出大量 HTML...
ob_end_flush(); // 瀏覽器收到已壓縮的 HTML
ob_start(),形成堆疊。ob_get_level() 回傳目前層級。ob_end_clean()、ob_flush() 等結束函數,否則行為未定義。chunk_size 參數:指定緩衝區達到多少位元組自動刷新,配合 ob_gzhandler 可實現分塊壓縮傳輸。flags 參數 (PHP 5.4+):PHP_OUTPUT_HANDLER_CLEANABLE、PHP_OUTPUT_HANDLER_FLUSHABLE、PHP_OUTPUT_HANDLER_REMOVABLE 控制緩衝區可被清理/刷新/移除。輸出控制是 PHP 進階開發的基石技能。掌握緩衝機制、回呼處理、巢狀管理,能解決 Header 衝突、實現頁面快取、優化前端傳輸、統一錯誤呈現等關鍵需求。