我试图找出为什么这个循环没有任何返回到浏览器:PHP无尽while循环混乱
while(1) {
echo "hello";
flush();
sleep(1);
}
我期待它返回“你好”到浏览器每一秒。 .. 我错了吗?现在这个页面似乎挂起了。
我试图找出为什么这个循环没有任何返回到浏览器:PHP无尽while循环混乱
while(1) {
echo "hello";
flush();
sleep(1);
}
我期待它返回“你好”到浏览器每一秒。 .. 我错了吗?现在这个页面似乎挂起了。
在收到整个页面之前,浏览器不会显示任何东西。 PHP不能完成你想要完成的任务。
在Javascript中,这很简单。
<script>
window.setInterval(function(){document.innerHTML += "<br> Hello"}, 1000)
</script>
PHP只在执行完成后输出。所以你所做的每一毫秒都会产生一个新的hello,并且由于你永远不会退出循环,所以你永远不会看到输出。
是什么flush()是为了什么? – mootymoots 2013-03-08 20:38:07
阅读刷新文档:http://php.net/manual/en/function.flush.php刷新“排序”的作品,但更多的时候,不是, – bizzehdee 2013-03-08 20:39:17
不正确,你可以真正输出一行,但你有到'flush()'并且确保'output_buffering'被禁用,或者调用'ob_flush()'作为valentin所说的 – 2013-03-27 11:29:06
您应该认识到PHP是一种脚本语言,因为它仅在完成脚本后才返回输出。编辑:或者输出缓冲区填充后,谢谢@Marc B. 无论我会说这是更聪明的使用JS或如果你真的需要你的服务器,使用AJAX请求。
也许你应该考虑使用Javascript?这将允许你每秒添加内容(请记住JS在客户端运行,所以你可能不想让你的操作全部扩展)。
或者你可以考虑使用AJAX请求例如JQuery的,但可能是这个问题的范围...
不完全正确。 PHP可以/会根据需要将输出发送给客户端。但只有当脚本完成和/或输出缓冲区填满时。很可能有一个php脚本发送无限数据,并且会很快显示在客户端。 – 2013-03-08 20:44:52
你说得很对,谢谢我解决了我的答案,以反映这个评论:) – MrHug 2013-03-08 20:48:42
添加到所有其他的答案,
要做到异步服务器推到客户端,您需要使用WebSockets。这是一个很大的课题,并没有完全标准化,但是确实有这样做的方法。如果您有兴趣搜索PHP Websockets。
也许是未为晚矣回答,但如果你想在这里刷新每一秒,我给你一个例子:
<?php
echo "Flushing every second ...\n";
flush();
$seconds = array (0,1,2,3,4,5,6,7,8,9);
foreach ($seconds as $second):
echo $second . "\n";
sleep(1);
@ob_flush(); flush();
endforeach;
echo 'I flashed 10 second :P';
要纠正我的答案,让你更好地理解,并为AJAX爱好者。 .. 你需要和额外的冲洗有..在 'ob_' 之一:
<?php
while(1):
echo "hello";
ob_flush(); flush();
sleep(1);
endwhile;
这是大家谁需要知道的 '特技';)
这不是一个好的答案,因为它不能可靠地工作(如果有的话),如文档[这里](http://stackoverflow.com/问题/ 5770917)和[ob_flush()的评论](http://www.php.net/manual/en/function.ob-flush.php#allnotes)。 AJAX是实现在所有浏览器中可靠且一致地提出问题的唯一方法。而无需修改服务器设置。 – mastaBlasta 2013-03-22 15:17:33
Valentin给了你正确的答案(upvote他/接受他的答案!),但没有解释为什么。这里的解释:
PHP不输出马上浏览器,等待有一些内容量发送到浏览器(可能是它发出的1024,2048或4096字节的块),或执行结束时。调用flush()
会使PHP发送数据,但有多个缓冲层。一个是内部缓冲(我刚刚评论过),但是你可以添加更多的缓冲层。假设此代码:
<?php
echo "hi";
setcookie('mycookie', 'somevalue');
?>
的setcookie()
函数发送一个HTTP报头到浏览器,但它不能这样做,因为在HTTP的服务器(或客户端,这是相同的两种方式),必须首先发送所有标题,空白行,然后是内容。正如你所看到的,你正在输出一些内容(hi)在标题之前,所以它失败(因为内部缓冲遵循相同的执行顺序)。
您可以使用php函数ob_*()
添加另一层输出缓冲。用ob
缓冲它只缓冲内容输出,而不是HTTP头。您可以使用它们来获取直接输出到浏览器的功能的输出,如var_dump()
。此外,您还可以巢层ob
:
<?php
// start first level of output buffering
ob_start();
echo "nesting at level ", ob_get_level(), "<br />\n"; // prints level 1
echo "hi<br />";
ob_start();
echo "nesting at level ", ob_get_level(), "<br />\n"; // prints level 2
var_dump($_POST);
$post_dump = ob_get_clean();
// this will print level 1, because ob_get_clean has finished one level.
echo "nesting at level ", ob_get_level(), "<br />\n";
echo "The output of var_dump(\$_POST) is $post_dump<br />\n";
// in spite of being inside a layer of output_buffering, this will work
setcookie('mycookie', 'somevalue');
// flush the current buffer and delete it (will be done automatically at the
// end of the script if not called explicitly)
ob_end_flush();
也许你的PHP服务器output_buffering默认情况下启用。默认情况下,请参阅configuration variables将其关闭/打开。
好吧,卡洛斯批评我,因为我没有解释我的答案,但他的答案是含糊不清......用饼干,图层...... POST,ob_levels ...:OO到很多信息,没有真正的关于真正的用户问题,但我会告诉你为什么你的代码不工作。因为你在php.ini设置的输出缓冲是这样的:
output_buffering = On
或
output_buffering = 4096 (default setting on most distributions)
这就是为什么你需要额外的“使用ob_flush()”,摆脱任何垃圾输出。 。
所以......为了让你的代码工作,你有两个选择:
1). set output_buffering = 0 or Off (if you have access to the php.ini)
2). ob_flush many times as layers of buffering you have
如果你不知道如何MA纽约层你有,你可以这样做:
while (@ob_end_clean());
和清洁每垃圾,你可以有,然后你的代码会工作得很好.. 完成snipp:
<?php
while (@ob_end_clean());
while(1) {
echo "hello";
flush();
sleep(1);
}
氰..
你的HTTP服务器正在缓冲输出 – galchen 2013-03-08 20:36:32
不是什么flush()的用途? – mootymoots 2013-03-08 20:38:28
排序,阅读http://php.net/manual/en/function.flush.php – galchen 2013-03-08 20:40:05