Output Buffering(輸出緩衝)是 PHP 4 引入的核心特性,解決了「Header 已送出無法修改」的經典問題,同時為進階輸出控制提供了強大工具。本文從 HTTP Header 原理切入,詳細說明輸出緩衝運作機制、基本 API 與實戰應用場景。
HTTP 回應包含兩部分:Header(標頭)與 Body(主體)。Header 必須在 Body 之前送出,兩者間以空行分隔。
HTTP/1.1 200 OK
Date: Sat, 02 Sep 2000 21:40:08 GMT
Content-Type: text/html
<html>...</html>
PHP 腳本執行時:
header()、setcookie()、session_start())不會立即輸出,而是暫存於內部列表。echo、HTML 直輸、空白字元),PHP 會強制送出所有暫存 Header,隨後送出空行結束 Header 階段。Cannot modify header information - headers already sent。啟用輸出緩衝後,腳本的所有輸出(含 echo、print、HTML 區塊)不會直接送往瀏覽器,而是暫存在記憶體緩衝區。此時 Header 仍可自由修改、新增。腳本結束或手動刷新時,PHP 依序送出 Header、空行、緩衝區內容。
| 函數 | 說明 |
|---|---|
ob_start() | 啟用輸出緩衝,支援多層嵌套(可重複呼叫) |
ob_end_flush() | 送出緩衝內容並關閉緩衝 |
ob_end_clean() | 丟棄緩衝內容並關閉緩衝 |
ob_get_contents() | 取得目前緩衝區內容(不清除) |
ob_get_clean() | 取得內容並清除緩衝(等同 ob_get_contents() + ob_end_clean()) |
ob_flush() | 刷新緩衝區送出內容(保持緩衝開啟) |
ob_clean() | 清空緩衝區(保持緩衝開啟) |
<?php
ob_start(); // 1. 啟用緩衝
echo 'Hello '; // 2. 寫入緩衝區
header('X-Custom: Value'); // 3. 此時仍可設定 Header
setcookie('test', 'value'); // 4. 設定 Cookie
$content = ob_get_clean(); // 5. 取得並清除緩衝
echo $content; // 6. 實際輸出
?>
ob_start();
include 'template.php'; // 模板內含變數輸出
$html = ob_get_clean();
file_put_contents('cache/page.html', $html); // 寫入靜態檔
echo $html;
ob_start('ob_gzhandler'); // 自動 gzip 壓縮(需瀏覽器支援)
echo '大量內容...';
ob_start();
some_legacy_function_that_echoes(); // 無法修改的舊函數
$output = ob_get_clean();
// 進一步處理 $output(如字串替換、記錄日誌)
ob_start(); // 層級 1
echo 'A';
ob_start(); // 層級 2
echo 'B';
$inner = ob_get_clean(); // 取得 'B'
echo 'C';
$outer = ob_get_clean(); // 取得 'AC'
echo $outer . $inner; // 輸出 'ACB'
output_buffering = 4096:全域啟用,緩衝區大小(位元組),On 表示無限大。生產環境建議設定具體數值(如 4096)。implicit_flush = Off:關閉隱含刷新,配合緩衝使用。ob_flush() + flush() 送出。ob_gzhandler 若輸出非文字內容(如圖片、PDF)可能導致損壞,需條件啟用。Output Buffering 不僅解決了 Header 輸出順序限制,更是實現模板渲染、內容過濾、壓縮傳輸、靜態快取等進階功能的基石,是 PHP 開發者必須掌握的核心機制。