Php 如何在每次“echo”调用后刷新输出?
我有一个只向客户端生成日志的php脚本。Php 如何在每次“echo”调用后刷新输出?,php,apache,echo,flush,Php,Apache,Echo,Flush,我有一个只向客户端生成日志的php脚本。 当我回显某个内容时,我希望它能够在运行中传输到客户端。 (因为在处理脚本时,页面是空白的) 我已经玩过ob\u start()和ob\u flush(),但它们都不起作用 最好的解决方案是什么 附言:在echo调用的末尾刷新有点脏 编辑:答案都不起作用,PHP或Apache错误 你想要的是方法。 例如: 正确使用的函数是flush() 你好我正在等待下一条消息… 我是下一条消息 我是最后一条信息。再见。 请注意,IE有一个“问题”,它只在刷新内容
当我回显某个内容时,我希望它能够在运行中传输到客户端。
(因为在处理脚本时,页面是空白的)
我已经玩过
ob\u start()
和ob\u flush()
,但它们都不起作用
最好的解决方案是什么
附言:在echo
调用的末尾刷新有点脏
编辑:答案都不起作用,PHP或Apache错误 你想要的是方法。
例如:
正确使用的函数是
flush()
你好我正在等待下一条消息…
我是下一条消息
我是最后一条信息。再见。
请注意,IE有一个“问题”,它只在刷新内容至少为256字节时才输出刷新内容,因此页面的第一部分需要至少为256字节。为什么不创建一个echo函数,如下所示:
function fecho($string) {
echo $string;
ob_flush();
}
编辑:
ob_implicit_flush(1);
for ($i=0; $i<10; $i++) {
echo $i;
// this is to make the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
sleep(1);
}
我在阅读手册页面上的评论时发现,ob\u implicit\u flush
不起作用,以下是解决方法:
ob_end_flush();
# CODE THAT NEEDS IMMEDIATE FLUSHING
ob_start();
如果这不起作用,那么甚至可能发生的情况是,在服务器建立足够的字符以发送它认为值得发送的数据包之前,客户端不会从服务器接收数据包
旧答案:
ob_implicit_flush(1);
for ($i=0; $i<10; $i++) {
echo $i;
// this is to make the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
sleep(1);
}
您可以使用以下命令来指示输出缓冲关闭缓冲一段时间:
ob_implicit_flush(true);
# CODE THAT NEEDS IMMEDIATE FLUSHING
ob_implicit_flush(false);
我也有类似的事情要做。使用
// ini_set("output_buffering", 0); // off
ini_set("zlib.output_compression", 0); // off
ini_set("implicit_flush", 1); // on
在我的情况下,输出经常刷新
但我必须在某个特定点(在我运行的循环中)刷新输出,所以使用这两种方法
ob_flush();
flush();
一起为我工作
我没能做到
使用关闭“输出缓冲”
ini_set(…),必须直接将其旋转
在php.ini中,phpinfo()显示其设置
关闭时为“无值”,是吗
正常吗
这就是我发现的 Flush在Apache的mod_gzip或Nginx的gzip下不起作用,因为从逻辑上讲,它是gzip内容,要做到这一点,它必须将内容缓冲到gzip中。任何类型的web服务器gzip都会影响这一点。简而言之,在服务器端,我们需要禁用gzip并减小fastcgi缓冲区大小。因此:
- 在php.ini中:
output_buffering = Off zlib.output_compression = Off
- 在nginx.conf中:
gzip off; proxy_buffering off;
@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 to make the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
sleep(1);
}
ob\u隐式\u刷新(1);
对于($i=0;$i),刷新失败是自动字符集检测的副作用
浏览器在知道要在其中显示的字符集之前不会显示任何内容,如果不指定字符集,它需要尝试猜测。问题是,如果没有足够的数据,它无法做出正确的猜测,这就是为什么浏览器似乎有1024字节(或类似字节)的原因在显示任何内容之前需要填充缓冲区
因此,解决方案是确保浏览器不必猜测字符集
如果您发送文本,请在其内容类型中添加“;charset=utf-8”,如果是HTML,请将字符集添加到相应的元标记中。我收到了相同的问题,并且手册中发布的一个示例已生效。必须将字符集指定为此处已提到的海报之一
标题('Content-type:text/html;charset=utf-8');
回显“开始…
”;
对于($i=0;$i<10;$i++)
{
回显$i。“
”;
冲洗();
ob_flush();
睡眠(1);
}
回显“结束…
”;
有时,问题来自Apache设置。可以将Apache设置为gzip输出。
在.htaccess文件中,您可以添加以下内容,例如:
SetEnv no-gzip 1
试试这个:
while (@ob_end_flush());
ob_implicit_flush(true);
echo "first line visible to the browser";
echo "<br />";
sleep(5);
echo "second line visible to the browser after 5 secs";
反病毒软件也可能会干扰输出刷新。在我的情况下,卡巴斯基反病毒2013在将数据块发送到浏览器之前保存了数据块,即使我使用的是公认的解决方案。注意,如果您在某些共享托管网站(如Dreamhost)上,如果不通过不同路线:
如果您使用的是PHP FastCGI,则更改输出缓冲区缓存
函数flush()、ob_flush()和ob_implicit_flush()将不会
按预期运行。默认情况下,输出缓冲在更高级别
而不是PHP(具体地说,是通过Apache模块mod_deflate
在形式/功能上类似于mod_gzip)
如果需要无缓冲输出,则必须使用CGI(而不是
FastCGI)或联系支持部门请求禁用mod_deflate
为您的网站
我的讨论迟到了,但我读到很多人说在每个代码的末尾添加flush();看起来很脏,他们是对的
最佳解决方案是禁用来自Apache、中间处理程序和PHP的deflate、gzip和所有缓冲。然后在PHP.ini中您应该有:
output_buffering = Off
zlib.output_compression = Off
implicit_flush = Off
临时解决方案是在php.ini中包含这个如果你可以用flush()解决你的问题;但是你认为把它放在任何地方都是肮脏和丑陋的
implicit_flush = On
如果只将其放在php.ini中,则不需要再将flush()放在代码中。这是我的代码:(为PHP7工作)
对于2018年即将到来的人:
唯一对我有效的解决方案是:
<?php
if (ob_get_level() == 0) ob_start();
for ($i = 0; $i<10; $i++){
echo "<br> Line to show.";
echo str_pad('',4096)."\n";
ob_flush();
flush();
sleep(2);
}
echo "Done.";
ob_end_flush();
?>
保留de“4096”部分非常重要,因为它似乎“填充”了缓冲区…这对我来说很好(Apache 2.4/PHP7.0):
@ob_end_clean();
回声“同侧眼底……”;
冲洗();
睡眠(5);
回声“
多洛……”;
冲洗();
睡眠(5);
回声“
坐在阿梅特”;
一件不常提及的事情是gzip压缩,由于各种托管环境中的细节,它一直处于打开状态
这是一个
implicit_flush = On
private function closeConnection()
{
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
ignore_user_abort(true);
set_time_limit(0);
ob_start();
// do initial processing here
echo json_encode(['ans' => true]);
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
ob_flush();
flush();
}
<?php
if (ob_get_level() == 0) ob_start();
for ($i = 0; $i<10; $i++){
echo "<br> Line to show.";
echo str_pad('',4096)."\n";
ob_flush();
flush();
sleep(2);
}
echo "Done.";
ob_end_flush();
?>
@ob_end_clean();
echo "lorem ipsum...";
flush();
sleep(5);
echo "<br>dolor...";
flush();
sleep(5);
echo "<br>sit amet";
output_buffering = 0
zlib.output_compression = 0
implicit_flush = true
output_handler =
header('Content-Encoding: none'); // Disable gzip compression
ob_end_flush(); // Stop buffer
ob_implicit_flush(1); // Implicit flush at each output command