默認情況下,PHP 執行 echo、HTML 輸出等內容會直接發送給瀏覽器。開啟輸出緩衝區(ob_start())後,所有輸出先存入內存緩衝區,直到腳本結束或調用 ob_end_flush() 才一次性發送。這解決了「Header already sent」錯誤,並啟用了靜態化、捕獲輸出等高級用法。
| 函數 | 作用 |
|---|---|
ob_start() | 開啟緩衝區 |
ob_get_contents() | 獲取緩衝區內容(字符串) |
ob_end_flush() | 輸出緩衝區內容並關閉緩衝區 |
ob_end_clean() | 清空緩衝區並關閉(不輸出) |
<?php
ob_start(); // 開啟緩衝區
echo "Hello\n"; // 正常情況下這會導致 header 失敗
header("Location: index.php"); // 重定向現在生效
ob_end_flush(); // 輸出並結束
?>
<?php
ob_start();
phpinfo(); // 直接輸出到瀏覽器的信息
$info = ob_get_contents(); // 捕獲到變量
$fp = fopen('info.txt', 'w');
fwrite($fp, $info);
fclose($fp);
ob_end_clean(); // 不輸出到頁面
?>
<?php
ob_start(); // 開啟緩衝區
?>
<html><body>
<h1>動態生成的內容</h1>
<p>當前時間:<?= date('Y-m-d H:i:s') ?></p>
</body></html>
<?php
$content = ob_get_contents(); // 獲取完整 HTML
$fp = fopen("page_".time().".html", "w");
fwrite($fp, $content);
fclose($fp);
ob_end_flush(); // 同時輸出給用戶
?>
function runCode($code) {
if (!$code) { echo "錯誤:無代碼"; exit; }
ob_start();
eval($code); // 高危!僅受信代碼
$output = ob_get_contents();
ob_end_clean();
return $output;
}
警告:eval() 極度危險,生產環境嚴禁使用未經極嚴格驗證的用戶輸入。
ob_start() 可多次調用,形成棧結構。內層 ob_get_contents() 只獲取當前層內容,配合回調函數可實現過濾、壓縮(如 ob_gzhandler)。
php.ini 設 output_buffering = 4096 自動為所有腳本開啟 4KB 緩衝,減少「Header already sent」錯誤。輸出緩衡區是 PHP 靈活控制 HTTP 響應的核心機制。善用它可解決重定向衝突、實現頁面靜態化、捕獲第三方庫輸出、構建模板引擎。但需注意內存佔用與嵌套層級管理。