PHP Flush有效......即使在Nginx中也是如此

时间:2011-02-02 04:11:00

标签: php nginx flush

每次循环执行时都可以回显吗?例如:

foreach(range(1,9) as $n){
    echo $n."\n";
    sleep(1);
}

我不想在循环结束时打印所有内容,而是希望每次打印每个结果。

8 个答案:

答案 0 :(得分:33)

最终解决方案

这就是我发现的:

Flush在Apache的mod_gzip或Nginx的gzip下不起作用,因为从逻辑上讲,它正在压缩内容,为此,它必须缓冲内容以对其进行gzip。任何类型的Web服务器gzipping都会影响这一点。简而言之,在服务器端,我们需要禁用gzip并减少fastcgi缓冲区大小。所以:

  • 在php.ini中:

    。 output_buffering =关

    。 zlib.output_compression =关

  • 在nginx.conf中:

    。 gzip off;

    。 proxy_buffering off;

还有这些线,特别是如果你没有访问php.ini:

  • @ini_set( '要用zlib.output_compression',0);

  • @ini_set( 'implicit_flush',1);

  • @ob_end_clean();

  • 参数或者set_time_limit(0);

最后,如果你拥有它,请注意以下代码:

  • ob_start( 'ob_gzhandler');

  • 使用ob_flush();

PHP测试代码:

ob_implicit_flush(1);

for($i=0; $i<10; $i++){
    echo $i;

    //this is for the buffer achieve the minimum size in order to flush data
    echo str_repeat(' ',1024*64);

    sleep(1);
}

相关:

答案 1 :(得分:32)

消除nginx缓冲的最简单方法是发出标题:

header('X-Accel-Buffering: no');

这消除了proxy_buffering和(如果你有nginx&gt; = 1.5.6),fastcgi_buffering。如果您使用php-fpm,fastcgi位是至关重要的。根据需要,标题也更方便。

Docs on X-Accel-Buffering Docs on fastcgi_buffering

答案 2 :(得分:25)

在nginx服务器上轻松解决方案:

fastcgi_keep_conn on; # < solution

proxy_buffering off;
gzip off;

答案 3 :(得分:10)

在一些特定情况下,我不想为整个服务器或整个目录关闭gzip,仅针对几个脚本。

所有你需要的就是在回声之前:

header('Content-Encoding: none;');

然后正常进行冲洗:

ob_end_flush();
flush();

Nginx似乎已经关闭了已关闭的编码,并且没有gzip。

答案 4 :(得分:5)

您需要将php的缓冲区刷新到浏览器

foreach(range(1,9) as $n){
    echo $n."\n";
    flush();
    sleep(1);
}

请参阅:http://php.net/manual/en/function.flush.php

答案 5 :(得分:2)

您可以通过在循环中间刷新输出缓冲区来实现此目的。

示例:

ob_start();
foreach(range(1,9) as $n){
    echo $n."\n";
    ob_flush();
    flush();
    sleep(1);
}

请注意,如果启用了zlib压缩,那么php.ini设置会影响这是否有效

答案 6 :(得分:2)

我发现你可以设置:

header("Content-Encoding:identity");

在你的php脚本中禁用nginx gzipping而不必修改nginx.conf

答案 7 :(得分:1)

我的php-fpm引擎出现了一个gzip问题。 这段代码是唯一适合我的代码:

function myEchoFlush_init() {
    ini_set('zlib.output_compression', 0);
    ini_set('output_buffering', 'Off');
    ini_set('output_handler', '');
    ini_set('implicit_flush', 1);
    ob_implicit_flush(1);
    ob_end_clean();
    header('Content-Encoding: none;');

}

function myEchoFlush($str) {
    echo $str . str_repeat(' ', ini_get('output_buffering') * 4) . "<br>\n";
}

这是我的测试功能:它检查max_execution_time:

public function timeOut($time = 1, $max = 0) {
    myEchoFlush_init();
    if ($max) ini_set('max_execution_time', $max);
    myEchoFlush("Starting infinite loop for $time seconds. It shouldn't exceed : " . (ini_get('max_execution_time')));
    $start = microtime(true);
    $lastTick = 1;
    while (true) {
        $tick = ceil(microtime(true) - $start);
        if ($tick > $lastTick) {
            myEchoFlush(microtime(true) - $start);
            $lastTick = $tick;
        }
        if ($tick > $time) break;
    }
    echo "OK";
}