使用 flush() 實現長時間任務的進度即時輸出時,常因輸出緩衝機制導致內容一次性輸出。本文提供 Linux/Windows 環境下的完整解決方案。
<?php
ob_start(); // 開啟 PHP 輸出緩衝
for ($i = 1; $i <= 10; $i++) {
echo $i . "<br />\n";
ob_flush(); // 刷新 PHP 緩衝到 Web 伺服器
flush(); // 刷新 Web 伺服器緩衝到瀏覽器
usleep(500000); // 模擬耗時任務 (0.5秒)
}
<?php
header("Content-Type: text/html; charset=utf-8");
// 關鍵:禁用 gzip 壓縮,否則輸出會被壓縮緩衝
header("X-Accel-Buffering: no"); // Nginx 禁用緩衝
header("Cache-Control: no-cache");
ob_start();
for ($i = 1; $i <= 10; $i++) {
echo $i . "<br />\n";
ob_flush();
flush();
usleep(500000);
}
| 環境 | 關鍵配置 |
|---|---|
| Apache + mod_php | 關閉 output_buffering,或在 .htaccess 設定 php_value output_buffering Off |
| Nginx + PHP-FPM | Nginx 配置 fastcgi_buffering off; proxy_buffering off; gzip off; |
| IIS + FastCGI | 關閉 responseBufferLimit,設置 output_buffering = Off |
| 瀏覽器 | 某些瀏覽器需接收 256-1024 bytes 才開始渲染,可輸出填充字符 |
// 在迴圈前輸出足夠填充
echo str_repeat(' ', 1024);
// 或輸出隱藏 HTML 註釋
echo '<!-- ' . str_repeat(' ', 1024) . ' -->';
flush() 不用 ob_flush():PHP 緩衝未刷新按環境依次排查配置,即可實現真正的即時輸出效果。