PHP 即時輸出技術:刷新緩衝區實現流式回應
預設 PHP 會將輸出緩存,待腳本結束一次性發送給瀏覽器。長時間任務(如匯出大量資料、批次處理)需即時顯示進度,必須控制輸出緩衝區。
核心代碼
<?php
set_time_limit(10); // 設定腳本最長執行秒數
ob_end_clean(); // 關閉並清空輸出緩衝區
echo str_pad('', 1024); // 發送 1024 位元組觸發瀏覽器開始渲染(IE 256、Firefox 1024)
for ($i = 1; $i <= 100; $i++) {
echo $i . '<br/>';
flush(); // 強制刷新 PHP 緩衝區到 Web Server
sleep(1); // 模擬耗時操作
}
?>
關鍵函數說明
| 函數 | 作用 |
ob_end_clean() | 關閉輸出緩衝並丟棄緩衝內容 |
flush() | 將 PHP 緩衝區資料推送到 Web Server(Apache/Nginx) |
str_pad('', 1024) | 發送足夠資料觸發瀏覽器開始顯示(各瀏覽器門檻不同) |
完整流程圖解
- PHP 腳本輸出 → PHP 內部緩衝區
flush() → Web Server 緩衝區
- Web Server 發送給瀏覽器(可能再經過 gzip、chunked encoding)
- 瀏覽器接收足夠資料 → 開始渲染
常見問題與解決方案
| 問題 | 原因 | 解決 |
| 完全不顯示、最後才一次出現 | Web Server(Nginx/Apache)啟用 gzip 或 proxy_buffering | Nginx 加 proxy_buffering off; gzip off;;Apache 確認 mod_deflate 未攔截 |
| 瀏覽器不顯示增量內容 | 資料量未達瀏覽器渲染門檻 | 定期發送 str_pad('', 1024) 或 HTML 註釋填充 |
| 腳本中途中斷 | 超過 max_execution_time 或前端逾時 | set_time_limit(0);前端用 AJAX 輪詢或 WebSocket |
現代替代方案
- Server-Sent Events (SSE):單向即時推送,HTTP 原生支援。
- WebSocket:雙向通訊,適合高頻互動。
- AJAX 長輪詢 / 短輪詢:相容性最好,實作簡單。
- 上一篇文章: PHP func_get_args、func_get_arg、func_num_args 差異詳解
- 下一篇文章: PHP file_get_contents 超時處理與重試機制完整指南
Copyright ©
程式碼之家 All Rights Reserved