PHP輸出控制涉及三層緩衝:PHP層(ob_*)、WebServer層(Apache/Nginx)、瀏覽器層。ob_flush 清空PHP緩衝,flush 推送至WebServer(僅Apache模組模式有效)。正確順序:ob_flush(); flush();。本文深度解析機制差異、Nginx+PHP-FPM配置、SSE長連接實戰代碼。
PHP腳本
↓ ob_flush() 清空PHP output_buffering
PHP內部緩衝區
↓ flush() 呼叫SAPI flush函數指針 (僅Apache模組有效)
Apache/Nginx 緩衝區
↓ 網路傳輸
瀏覽器接收緩衝區
↓ 瀏覽器渲染邏輯 (如IE需256字節才顯示、表格需才渲染)
用戶可見內容
| 函數 | 作用層級 | 生效條件 | 說明 |
|---|---|---|---|
| ob_flush() | PHP層 | 啟用 output_buffering | 刷新PHP內部緩衝至SAPI |
| flush() | WebServer層 | PHP為Apache模組 (handler/filter) | 調用 ap_rflush 刷新Apache緩衝 |
注意:Nginx + PHP-FPM (FastCGI) 下 flush() 無效,需配合 Nginx 配置。
mod_gzip、mod_deflate 可能自行緩衝導致 flush 延遲str_repeat(' ', 4096) 填充)output_buffering、implicit_flush、zlib.output_compressionif (ob_get_level() == 0) ob_start();
echo str_repeat(' ', 4096); // 填充觸發瀏覽器渲染
while ($condition) {
echo "data: {$data}\n\n"; // SSE格式
ob_flush(); // 1. PHP層 → SAPI
flush(); // 2. SAPI → WebServer → 客戶端
sleep(1);
}
header('X-Accel-Buffering: no');
作用:關閉 Nginx proxy_buffering 與 fastcgi_buffering(需 Nginx 1.5.6+),對 PHP-FPM 至關重要。比修改 nginx.conf 更靈活。
0) {
$time = date('r');
echo "data: The server time is: {$time}\n\n";
ob_flush();
flush();
sleep(1);
}
?>
0) {
$time = date('r');
echo "data: The server time is: {$time}\n\n";
ob_flush();
flush();
sleep(1);
}
?>
var source = new EventSource("/sse.php");
source.onmessage = function(event) {
console.log(event.data); // "The server time is: ..."
};
ob_flush(); flush(); 成對使用,保證可移植性X-Accel-Buffering: no (Nginx)zlib.output_compression 避免雙重壓縮干擾