<?php
for ($i = 10; $i > 0; $i--) {
echo $i;
flush();
sleep(1);
}
// 預期:每秒輸出一個數字
// 實際:等 10 秒一次性輸出全部
php.ini 中 output_buffering = 4096 (4KB) 導致 PHP 內部緩衝,未達 4KB 或腳本結束不輸出。
ob_end_clean(); // 或 ob_end_flush() // 後續 echo + flush() 即可即時輸出
for ($i = 10; $i > 0; $i--) {
echo $i;
ob_flush(); // 將 PHP 緩衝區資料推送到 Web Server
flush(); // 將 Web Server 緩衝區資料推送到瀏覽器
sleep(1);
}
ob_implicit_flush(true); // 每次輸出自動 flush
for ($i = 10; $i > 0; $i--) {
echo $i;
ob_flush(); // 若 output_buffering 開啟仍需此行
sleep(1);
}
// 或完全關閉緩衝
ob_end_clean();
ob_implicit_flush(true);
for ($i = 10; $i > 0; $i--) {
echo $i;
sleep(1);
}
| 函數 | 作用層級 | 行為 | 是否關閉緩衝 |
|---|---|---|---|
ob_start() | PHP | 開啟輸出緩衝 | 否 |
ob_flush() | PHP | 刷新 PHP 緩衝區到 Web Server | 否 |
ob_end_flush() | PHP | 刷新並關閉緩衝 | 是 |
ob_end_clean() | PHP | 丟棄緩衝內容並關閉緩衝 | 是 |
flush() | Web Server | 刷新 Web Server 緩衝到瀏覽器 | 否 |
ob_implicit_flush() | PHP | 設定每次輸出自動刷新 | 否 |
multipart/x-mixed-replace 實現動態替換<?php
header('Content-type: multipart/x-mixed-replace;boundary=endofsection');
print "\n--endofsection\n";
$pmt = ["-", "\\", "|", "/"];
for ($i = 0; $i < 10; $i++) {
sleep(1);
print "Content-type: text/plain\n\n";
print "Part $i\t" . $pmt[$i % 4];
print "--endofsection\n";
ob_flush(); flush();
}
print "Content-type: text/plain\n\n";
print "The end\n";
print "--endofsection--\n";
腳本啟動時緩衝機制已初始化完成,ini_set() 只影響後續 include/require 的檔案,無法改變當前腳本的緩衝行為。
ob_end_clean(); ob_implicit_flush(true); + 定期 echo 進度fread 迴圈 + ob_flush(); flush(); 避免記憶體暴增proxy_buffering off; 避免 Nginx 二次緩衝