You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中flush()函数在Safari中无效的原因及解决办法

实时输出PHP耗时脚本内容的跨浏览器兼容方案

我有一个耗时的PHP脚本,需要向用户提供实时反馈。简化后的脚本在Firefox中能即时刷新输出,但Safari要等所有内容生成后才显示,Chrome直接报错ERR_CONTENT_DECODING_FAILED。

原脚本代码

<?php
ini_set('max_execution_time', 0);
header('Content-Encoding: none;'); 
header('Content-type: text/html; charset=utf-8');

$j = 8;
$k = pow(2, 10);

echo "One moment please...".str_pad('', $k)."<br />
<br />
";
flush();

$i = 0;
while ($i < $j) { 
    $i++;
    echo "Test ".$i.str_pad('',$k)."<br />
";
    flush();
    sleep(1);
} 
?>

已尝试的无效操作

  • 在.htaccess中添加SetEnv no-gzip 1或SetEnv no-gzip dont-vary
  • 开启/关闭output_buffering
  • 设置ob_start(null, 4096)
  • 关闭zlib.output_compression
  • 添加Cache-Control、X-Content-Type-Options、X-Accel-Buffering等响应头
  • 调整str_pad的长度
  • 在flush()前后添加@ob_flush()

针对PHP 8.1+FastCGI环境的解决方案

关键修复步骤

  1. 移除错误的编码头
    原脚本中header('Content-Encoding: none;');是Chrome报错的直接原因,直接删除该行即可解决解码失败问题。

  2. 强制关闭全链路输出缓冲
    在脚本开头添加代码,确保PHP层面和所有已启动的输出缓冲区都被关闭:

    ini_set('output_buffering', 'off');
    ini_set('zlib.output_compression', false);
    while (ob_get_level() > 0) {
        ob_end_flush();
    }
    
  3. 添加FastCGI专属禁用缓冲头
    FastCGI环境下必须通过X-Accel-Buffering: no告知服务器不要缓冲输出:

    header('X-Accel-Buffering: no');
    
  4. 确保浏览器触发刷新
    保持str_pad生成足够长度的内容(1KB以上),同时每次输出后必须执行ob_flush() + flush()组合操作,确保内容被推送到浏览器。

完整修复后的脚本

<?php
ini_set('max_execution_time', 0);
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);

// 关闭所有已开启的输出缓冲区
while (ob_get_level() > 0) {
    ob_end_flush();
}

header('Content-type: text/html; charset=utf-8');
header('X-Accel-Buffering: no');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

$j = 8;
$k = pow(2, 10);

echo "One moment please..." . str_pad('', $k) . "<br>\n<br>\n";
ob_flush();
flush();

$i = 0;
while ($i < $j) { 
    $i++;
    echo "Test " . $i . str_pad('', $k) . "<br>\n";
    ob_flush();
    flush();
    sleep(1);
} 
?>

额外说明

  • FastCGI环境下,.htaccess的压缩禁用配置可能被服务器全局设置覆盖,必须通过PHP代码直接禁用压缩和缓冲。
  • Safari对输出内容的触发阈值更高,1KB的空白填充足够让浏览器实时渲染新内容。

内容的提问来源于stack exchange,提问作者Sanderadio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:47:29