許多開發者期望在循環中每隔一秒輸出一個數字,實現「即時輸出」效果。然而直接使用 flush() 往往失效,導致腳本結束時一次性輸出所有內容。
PHP 預設啟用 output_buffering(php.ini 中通常設為 4096 bytes)。輸出會先存入 PHP 內部緩衝區,直到達到閾值或腳本結束才發送給 Web 服務器(再由服務器發送給瀏覽器)。單獨呼叫 flush() 僅能將 Web 服務器緩衝區的資料推送給瀏覽器,無法觸發 PHP 內部緩衝區的釋放。
<?php
echo str_pad('', 256); // 觸發瀏覽器開始渲染(IE 需 256 bytes)
ob_end_clean(); // 或 ob_end_flush(),終止並清空/發送 PHP 緩衝區
for ($i = 10; $i > 0; $i--) {
echo $i;
flush(); // 推送至瀏覽器
sleep(1);
}
?>
ob_end_clean() 與 ob_end_flush() 都會關閉當前輸出緩衝,差別在於前者丟棄緩衝內容,後者發送緩衝內容。此法需在腳本最開頭呼叫。
<?php
echo str_pad('', 256);
for ($i = 10; $i > 0; $i--) {
echo $i;
ob_flush(); // 將 PHP 內部緩衝區資料推送到 Web 服務器緩衝區
flush(); // 將 Web 服務器緩衝區資料推送到瀏覽器
sleep(1);
}
?>
此法不關閉緩衝,而是每次迭代手動觸發 ob_flush() + flush() 雙重刷新。
<?php
ob_implicit_flush(true); // 強制每次輸出自動刷新
echo str_pad('', 256);
for ($i = 10; $i > 0; $i--) {
echo $i;
ob_flush(); // 若 output_buffering 為 0 可省略
sleep(1);
}
?>
ob_implicit_flush(true) 讓每個輸出語句(echo、print 等)自動執行 flush(),但若 PHP 緩衝區仍存在(output_buffering > 0),仍需搭配 ob_flush()。
str_pad('', 256)。<br>。output_buffering = 0 或使用 ob_implicit_flush,避免在代碼中散佈緩衝控制邏輯。| 方法 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| ob_end_clean/flush | 腳本開頭一次性關閉緩衝 | 簡單,後續只需 flush() | 無法在腳本中途恢復緩衝 |
| ob_flush + flush | 需保留緩衝機制,逐步輸出 | 靈活控制每次刷新時機 | 代碼較繁瑣 |
| ob_implicit_flush | 長時間運行腳本、即時日誌 | 代碼乾淨,自動處理 | 受 output_buffering 影響,可能仍需 ob_flush |