首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

深入理解 ob_flush 與 flush 差異:PHP 輸出緩衝區與 Web Server 緩衝區的協作機制

     編輯:PHP 相關知識

ob_flush vs flush:兩個緩衝區、一個正確順序,徹底搞懂 PHP 即時輸出原理

許多開發者混淆 ob_flush 與 flush,甚至以為它們功能相同。實際上它們操作不同層級的緩衝區,正確搭配才能實現真正的即時輸出 (如長時間任務進度顯示)。

核心差異

函數操作對象生效條件
ob_flush()PHP 內部輸出緩衝區啟用 ob_start() 或 output_buffering 時
flush()Web Server (Apache/Nginx) 輸出緩衝區PHP 以 Apache Module (handler/filter) 運行時

運作流程

  1. PHP 產生輸出 → 存入 PHP 緩衝區 (ob_*)
  2. ob_flush() 將 PHP 緩衝區內容推送到 Web Server 緩衝區
  3. flush() 強制 Web Server 將資料發送給瀏覽器

正確使用順序

ob_start(); // 啟用 PHP 輸出緩衝
// ... 產生輸出 ...
ob_flush(); // 1. 先刷新 PHP 緩衝區
flush();    // 2. 再刷新 Web Server 緩衝區
為什麼要這個順序?
若先 flush(),Web Server 緩衝區可能尚無資料 (PHP 緩衝區未釋放);先 ob_flush() 確保資料已到達 Web Server 層,再 flush() 推送給客戶端。

特殊情況與坑點

  • CGI/FastCGI 模式:flush() 可能無效,因無直接控制 Web Server 緩衝區權限。
  • mod_gzip / mod_deflate:Apache 壓縮模組會自行緩存,導致 flush() 不即時生效。
  • 瀏覽器緩存:IE 需 256 bytes 才開始渲染,Netscape 待 </table> 才顯示表格。解決:輸出足夠空白字元或 <br>。
  • 其他 SAPI (CLI 等):只需 ob_flush(),但為可移植性建議雙函數配套使用。

實戰範例:長時間任務進度顯示

<?php
ob_start();
for ($i = 1; $i <= 10; $i++) {
    echo "處理第 $i 步...<br>\n";
    ob_flush();
    flush();
    sleep(1); // 模擬耗時操作
}
echo "完成!";
?>

補充:輸出緩衝控制函數家族

  • ob_start():開啟輸出緩衝
  • ob_get_contents():取得緩衝區內容
  • ob_clean():清空緩衝區
  • ob_end_flush():輸出並關閉緩衝
  • ob_end_clean():清空並關閉緩衝
參考來源:Laruence 博客深度解析
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved