首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

PHP 阻塞場景下分批輸出:ob_flush + flush 雙重刷新與現代替代方案

     編輯:程式設計綜合問答

問題代碼

ob_start();
for ($i = 0; $i < 20; $i++) {
    // 耗時操作 3秒
    echo "ABC";
    ob_flush(); // 僅刷新 PHP 輸出緩衝區
}

結果:60 秒後一次性輸出 20 個 ABC。

原因

輸出鏈路:PHP output_buffering → Web 服務器緩衝(nginx/apache) → 瀏覽器緩衝。
ob_flush() 僅刷新 PHP 層,Web 服務器與瀏覽器仍攔截。

傳統強制刷新(Hack)

@ob_end_clean(); // 關閉輸出緩衝
for ($i = 0; $i < 20; $i++) {
    // 耗時操作
    echo "ABC" . str_repeat(' ', 256); // 填滿瀏覽器緩衝區(IE 需 256+ 字節)
    ob_flush(); // PHP 層
    flush();    // Web 服務器層(需 php.ini: output_buffering = Off / implicit_flush = On)
    sleep(3);
}

缺點:依賴服務器配置、瀏覽器行為不一致、佔用長連接、易觸發超時、不利於擴展。

現代最佳實踐

  1. Ajax 輪詢:前端定時請求進度接口,後端返回當前進度/狀態。
    — 簡單、無狀態、易負載均衡。
  2. Server-Sent Events (SSE):HTTP 長連接,服務端單向推送文本事件。
    — 輕量、自動重連、支持斷點續傳。
    // 服務端
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    for ($i = 0; $i < 20; $i++) {
        echo "data: ABC\n\n";
        ob_flush(); flush();
        sleep(3);
    }
  3. WebSocket:全雙工雙向通訊,適合高頻實時交互。
    — 需 WebSocket 服務器支持。

選擇建議

  • 簡單進度條 → Ajax 輪詢(每 1-2 秒請求一次)。
  • 實時日志/通知流 → SSE(原生 HTTP、穿透代理)。
  • 聊天/協作編輯 → WebSocket。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved