輸出緩衝 是 PHP 將腳本輸出暫存於記憶體而非直接發送給瀏覽器的機制。核心函數 ob_start()、ob_get_contents()、ob_end_flush()、ob_clean() 組合可實現:HTTP 標頭延後發送、頁面內容捕獲、靜態 HTML 生成、模板渲染隔離 等高級用法。
| 函數 | 作用 | 返回值 |
|---|---|---|
| ob_start(callable $callback = null, int $chunk_size = 0, int $flags = PHP_OUTPUT_HANDLER_STDFLAGS) | 開啟緩衝,可選回調處理輸出 | bool |
| ob_get_contents() | 獲取緩衝區當前內容 | string / false |
| ob_get_clean() | 獲取內容並刪除緩衝區(等同 ob_get_contents + ob_end_clean) | string |
| ob_end_flush() | 發送緩衝內容並關閉緩衝 | bool |
| ob_end_clean() | 丟棄緩衝內容並關閉緩衝 | bool |
| ob_flush() | 發送緩衝內容但保持緩衝開啟 | bool |
| ob_clean() | 清空緩衝內容但保持緩衝開啟 | bool |
<?php
ob_start(); // 開啟緩衝,所有 echo 輸出暫存
echo "正在處理...";
// 業務邏輯...
header('Content-Type: application/json'); // 此時仍可發送 header,因輸出未真正發送
echo json_encode(['status' => 'ok']);
ob_end_flush(); // 統一發送
?>
<?php
$templateFile = 'template/article.php';
$outputFile = 'html/article_123.html';
ob_start();
include $templateFile; // 模板內 echo 變量、邏輯
$html = ob_get_clean(); // 獲取並清空緩衝
// 寫入靜態文件
if (file_put_contents($outputFile, $html) === false) {
throw new RuntimeException("靜態文件寫入失敗: $outputFile");
}
// 可選:直接輸出給瀏覽器
echo $html;
?>
<?php
// 外層:壓縮 HTML(移除多餘空白)
ob_start(function ($buffer) {
return preg_replace('/>\s+', '><', $buffer); // 簡易壓縮
});
// 內層:捕獲局部片段
ob_start();
include 'widgets/sidebar.php';
$sidebar = ob_get_clean();
include 'layout/main.php'; // 使用 $sidebar 變量
ob_end_flush(); // 外層回調自動處理最終輸出
?>
<?php
// 關閉輸出緩衝,直接發送
while (ob_get_level()) ob_end_clean();
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
$out = fopen('php://output', 'w');
fputcsv($out, ['ID', 'Name', 'Email']);
foreach ($largeDataset as $row) {
fputcsv($out, $row);
// 可選:定期 flush 給瀏覽器進度感
if (++$i % 1000 === 0) flush();
}
fclose($out);
?>
ob_get_level() 返回當前緩衝層數,避免不匹配的 ob_end_* 導致錯誤。output_buffering php.ini 設定:預設 4096 字節內部緩衝,影響 headers_sent() 判斷,建議代碼中顯式 ob_start() 掌控。try/finally 中確保 ob_end_clean() 執行,防止緩衝洩漏導致輸出重複或 header 失效。function callback(string $buffer, int $phase): string,$phase 含 PHP_OUTPUT_HANDLER_START、CONT、END、FINAL 等標記。