php php刷新不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4706525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 14:04:21  来源:igfitidea点击:

php flush not working

phpflush

提问by Speedy Wap

<?php
for($i=0;$i<20;$i++)
{
    echo 'printing...<br />';
    ob_flush();
    flush();

    usleep(300000);
}

?>

Url that contains the code: http://domainsoutlook.com/sandbox/delayed.php

包含代码的 URL:http: //domainsoutlook.com/sandbox/delayed.php

I have a dedicated server so I can make the changes. I am running apache and nginx as the proxy server.

我有一个专用服务器,所以我可以进行更改。我正在运行 apache 和 nginx 作为代理服务器。

采纳答案by schnaader

You're using ob_flushwithout ob_start, so there is nothing to flush for it.

您正在使用ob_flushwithout ob_start,因此没有什么可冲洗的。

It also depends on the webserver and proxy and its settings.

它还取决于网络服务器和代理及其设置。

You should disable buffering for Nginx (add proxy_buffering off;to the config file and restart Nginx)

您应该禁用 Nginx 的缓冲(添加proxy_buffering off;到配置文件并重新启动 Nginx)

Also, check if your php.inicontains output_buffering = Offand zlib.output_compression = Off.

另外,检查您的php.ini 是否包含output_buffering = Offzlib.output_compression = Off

回答by Roger

So that's what I found out:

所以这就是我发现的:

Flush would not work under Apache's mod_gzip or Nginx's gzip because, logically, it is gzipping the content, and to do that it must buffer content to gzip it. Any sort of web server gzipping would affect this. In short, at the server side, we need to disable gzip and decrease the fastcgi buffer size. So:

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

  • In php.ini:

    . output_buffering = Off

    . zlib.output_compression = Off

  • In nginx.conf:

    . gzip off;

    . proxy_buffering off;

  • 在 php.ini 中:

    . 输出缓冲 = 关

    . zlib.output_compression = 关

  • 在 nginx.conf 中:

    . gzip关闭;

    . 代理缓冲关闭;

Also have this lines at hand, specially if you don't have acces to php.ini:

手头也有这些行,特别是如果您没有访问 php.ini 的权限:

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

  • @ini_set('implicit_flush',1);

  • @ob_end_clean();

  • set_time_limit(0);

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

  • @ini_set('implicit_flush',1);

  • @ob_end_clean();

  • 设置时间限制(0);

Last, if you have it, coment the code bellow:

最后,如果你有的话,评论下面的代码:

  • ob_start('ob_gzhandler');

  • ob_flush();

  • ob_start('ob_gzhandler');

  • ob_flush();

PHP test code:

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);
}

回答by Emin Kad?o?lu

Main php file;

主php文件;

<?php
header('Content-Type: text/HTML; charset=utf-8');
header( 'Content-Encoding: none; ' );//disable apache compressed
session_start();
ob_end_flush();
ob_start();
set_time_limit(0);
error_reporting(0);

..... bla bla

for(each)........
{
   bla bla..
    echo "<br>>>>".$i."<<<br>";
    ob_flush();
    flush(); //ie working must

}
?>

it's working..

它的工作..

回答by Ankit Sharma

You have to fill the buffer, so that it can be flushed to browser. Use this after echo

您必须填充缓冲区,以便将其刷新到浏览器。在 echo 之后使用这个

echo str_pad('',4096)."\n";

Complete code:

完整代码:

<?php
     if (ob_get_level() == 0) ob_start();

     for( $i=0 ; $i<20 ; $i++) {
        echo 'printing...<br />';
        echo str_pad('',4096)."\n";

        ob_flush();
        flush();

        usleep(300000);
     }
     ob_end_flush();
?>

回答by Rodrigo Gregorio

In php.ini:

php.ini 中

output_buffering = Off
zlib.output_compression = Off

In nginx.conf:

nginx.conf 中

fastcgi_keep_conn on; # < solution
proxy_buffering off;
gzip off;

回答by Chris Koston

Another possible cause is mod_security. It looks like it has it's own buffers. So if you are using it you will have to set :

另一个可能的原因是 mod_security。看起来它有自己的缓冲区。因此,如果您正在使用它,则必须设置:

SecResponseBodyAccess Off

Kind of a dirty workaround but so far that it the only way I got it to work.

一种肮脏的解决方法,但到目前为止,这是我让它工作的唯一方法。

回答by dcaillibaud

As I read, it seems a really hard problem to solve, and the only (dirty) way I found is writing something useless to output to fill the ≠ buffers.

在我读到的时候,这似乎是一个很难解决的问题,我发现的唯一(肮脏)方法是写一些无用的输出来填充 ≠ 缓冲区。

  • Without SSL
    • Without output_buffering, flushis needed.
      nginx buffers can be lowered until the PHP header size
    • With output_buffering, ob_flushneed to be added to have the same behavior as above
  • With SSL
    • There is another buffer for SSL and NGX_SSL_BUFSIZEis fixed in nginx compilation
  • 没有 SSL
    • 没有 output_buffering,flush是需要的。
      可以降低 nginx 缓冲区直到 PHP 标头大小
    • 使用 output_buffering,ob_flush需要添加与上面相同的行为
  • 使用 SSL
    • SSL还有另一个缓冲区,NGX_SSL_BUFSIZE在nginx编译中修复

Here is my test.php file (call it with ?size=...to change space writing in the loop)

这是我的 test.php 文件(调用它?size=...以更改循环中的空间写入)

<!DOCTYPE html>
<html>
<head></head>
<body>
<?php
$vars = array('output_buffering', 'zlib.output_compression');
print('<p>');
foreach ($vars as $var) {
  print("$var : ");
  var_dump(ini_get($var));
  print('<br />');
}
print("ob_get_level() : " .ob_get_level());
print('</p>');
if (ob_get_level()) {
  $bytes = ob_get_length();
  ob_flush();
}

$nb_iterations = !empty($_GET['nb']) ? max(2, (int) $_GET['nb']) : 5;
$size = !empty($_GET['size']) ? $_GET['size'] : 0;

for ($i = 1; $i < $nb_iterations; $i++) {
  sleep(1);
  print(str_repeat(' ', 1024 * $size ));
  print("<p>wait $i s</p>");
  if (ob_get_level()) {
    $bytes += ob_get_length();
    print($bytes + strlen($bytes));
    ob_flush(); // this is working, results aren't depending on output_buffering value
  }
  flush(); // this is needed  
}
?>
</body>
</html>

And the lower conf I can set is

我可以设置的较低配置是

location ~ ^/test.php$ {
  gzip off;
  fastcgi_pass   unix:/var/run/php5-fpm/ssl.socket;
  fastcgi_param   QUERY_STRING            $query_string;  
  fastcgi_param   REQUEST_METHOD          $request_method;
  fastcgi_param   SCRIPT_FILENAME         $request_filename;   
  # if too low => upstream sent too big header while reading response header from upstream
  fastcgi_buffer_size 128; 
  fastcgi_buffers 2 128;  
  fastcgi_busy_buffers_size 128;
}

回答by Lukasz

Just wanted to add to the Roger's answer.

只是想补充罗杰的答案。

If you are using FastCGI php5-fpmmodule within Apache2you must also make sure you are adding

如果您在Apache2中使用 FastCGI php5-fpm模块,您还必须确保添加

-flush

-冲洗

argument in your Apache2 configuration, i.e.

Apache2 配置中的参数,即

<IfModule mod_fastcgi.c>
...
        FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -flush -socket /tmp/php5-fpm.sock -idle-timeout 480 -pass-header Authorization
</IfModule>

回答by gsm

Check your server api with

检查您的服务器api

echo phpinfo();

If you found your server api

如果你找到了你的服务器 api

Server API :  CGI/FastCGI

in CentOS then add this line in "/etc/httpd/conf.d/fcgid.conf"

在 CentOS 中,然后在“/etc/httpd/conf.d/fcgid.conf”中添加这一行

OutputBufferSize 0

To test, restart your Apache server and try below code

要测试,请重新启动 Apache 服务器并尝试以下代码

ob_start();
for($i = 0; $i < 10; $i ++) {
    echo $i;
    echo '<br />';
    flush();
    ob_flush();
    sleep(1);
}

回答by RahulD

if(!ob_get_level()) ob_start();
echo json_encode(array('valid'=>true,'msg'=>'Flush occured.'));
$size = ob_get_length();
header("Content-Type: application/json");
// Set the content length of the response.
header("Content-Length: {$size}");
//Close the connection if you want to.
header("Connection: close");
// Flush all output.
ob_end_flush();
ob_flush();
flush();
// Close current session (if it exists).
if(session_id()) session_write_close();