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

PHP flush() 無法實時輸出的解決方案:ob_flush + header 雙保險

     編輯:PHP 相關知識

長時間運行腳本(如導出大文件、爬蟲進度條)需實時向瀏覽器輸出進度。單用 flush() 常因 PHP 輸出緩衝、Web 服務器緩衝、瀏覽器緩衝導致無效。本文給出 Linux/Windows 通用的「三層緩衝突破」方案。

核心代碼模板

<?php
// 1. 關鍵:發送 Header 告訴瀏覽器不緩存、開始輸出
header('Content-Type: text/html; charset=utf-8');
header('X-Accel-Buffering: no'); // 關閉 Nginx fastcgi_buffering(關鍵!)

// 2. 開啟 PHP 輸出緩衝控制
ob_start(); // 開啟輸出緩衝
ob_implicit_flush(true); // 可選:隱式刷新(每次輸出自動 flush)

for ($i = 1; $i <= 10; $i++) {
    echo $i . '<br />' . "\n";

    // 3. 三層刷新:PHP ob_flush → PHP flush → 系統級 flush
    ob_flush(); // 刷新 PHP 內部緩衝區到 SAPI
    flush();    // 刷新 SAPI 到 Web 服務器/客戶端

    usleep(500000); // 模擬耗時操作 0.5 秒
}

ob_end_flush(); // 結束
?>

三層緩衝機制圖解

[PHP 代碼 echo/print]
        ↓
[PHP 內部 output_buffering (ob_start)]
        ↓ ob_flush()
[SAPI 層 (mod_php/php-fpm)]
        ↓ flush()
[Web 服務器 (Apache/Nginx) 緩衝區]
        ↓ (需關閉 gzip/buffering)
[網絡傳輸]
        ↓
[瀏覽器緩衝區 (通常需 >256 字節才渲染)]
        ↓
[用戶可見]

關鍵配置檢查清單

層級配置項建議值/操作位置
PHPoutput_bufferingOff 或 0php.ini / .user.ini / ini_set()
PHPzlib.output_compressionOffphp.ini
Nginxfastcgi_bufferingofflocation 塊或 http 塊
Nginxgzipoff (對該 location)location 塊
Apachemod_deflate / mod_gzip關閉或排除該路徑.htaccess / httpd.conf
瀏覽器最小渲染字節輸出 > 256 字節或用 <br> 強制換行代碼中控制

Nginx + PHP-FPM 專用關鍵配置

# nginx.conf 或 site conf location 塊
location ~ \.php$ {
    fastcgi_pass   unix:/run/php/php8.1-fpm.sock;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
    # 關鍵兩行:
    fastcgi_buffering off;        # 禁用 FastCGI 緩衝,實時推送
    proxy_buffering off;          # 若有反代層也要關
}

常見坑點

  • 輸出太少瀏覽器不渲染:每次 echo str_repeat(' ', 256) 填充或用 <br> 換行觸發渲染。
  • 開啟了 gzip 壓縮:壓縮需等待數據填滿窗口才發送,必須關閉(header('Content-Encoding: none') 或 Nginx 關 gzip)。
  • PHP-FPM request_terminate_timeout:長任務超過此值會被 kill,需調大或用 CLI 模式跑後台任務。
  • Windows IIS:需關閉「動態壓縮」並設置 responseBufferLimit="0"。

現代替代方案:Server-Sent Events (SSE) / WebSocket

若需雙向實時或高頻推送,建議遷移至 SSE(單向、HTTP 兼容、自動重連)或 WebSocket(雙向),避開 HTTP 短輪詢/長連接的緩衝地獄。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved