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
php flush not working
提问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_flush
without ob_start
, so there is nothing to flush for it.
您正在使用ob_flush
without 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 = Off
and zlib.output_compression = Off
.
另外,检查您的php.ini 是否包含output_buffering = Off
和zlib.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,
flush
is needed.
nginx buffers can be lowered until the PHP header size - With output_buffering,
ob_flush
need to be added to have the same behavior as above
- Without output_buffering,
- With SSL
- There is another buffer for SSL and
NGX_SSL_BUFSIZE
is fixed in nginx compilation
- There is another buffer for SSL and
- 没有 SSL
- 没有 output_buffering,
flush
是需要的。
可以降低 nginx 缓冲区直到 PHP 标头大小 - 使用 output_buffering,
ob_flush
需要添加与上面相同的行为
- 没有 output_buffering,
- 使用 SSL
- SSL还有另一个缓冲区,
NGX_SSL_BUFSIZE
在nginx编译中修复
- SSL还有另一个缓冲区,
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();