PHP无尽的循环混乱

时间:2013-03-08 20:34:59

标签: php while-loop

我正在试图弄清楚为什么这个循环不会向浏览器返回任何内容:

while(1) {
    echo "hello";
    flush();
    sleep(1);
}

我希望它每秒都能向浏览器“回报”...我错了吗?现在页面似乎挂了。

8 个答案:

答案 0 :(得分:3)

PHP仅在执行完成后输出。所以你所做的就是每隔几毫秒产生一个新的问候,因为你永远不会退出循环,你永远不会看到输出。

答案 1 :(得分:2)

纠正我的回答并让你更好地理解,并为AJAX爱好者...... 你需要和额外的冲洗...'ob_'一个:

<?php
while( 1 ):
    echo "hello";
    ob_flush( ); flush();
    sleep( 1 );
endwhile;

这是每个需要知道的人的“技巧”;)

答案 2 :(得分:0)

在收到整个页面之前,浏览器不会显示任何内容。 PHP无法满足您的目标。

在Javascript中,这很简单。

<script>
    window.setInterval(function(){document.innerHTML += "<br> Hello"}, 1000)
</script>

答案 3 :(得分:0)

您应该意识到PHP是一种脚本语言,因为它只在完成脚本后才返回输出。编辑:或者在输出缓冲区填满后,感谢@Marc B. 无论我怎么说使用JS是明智的,或者如果你真的需要你的服务器,请使用AJAX请求。

也许您应该考虑使用Javascript?这将允许您每秒添加内容(请记住,JS虽然在客户端运行,因此您可能不希望使您的操作完全扩展。)

或者你可以考虑通过例如JQuery使用AJAX请求,但这可能超出了这个问题的范围......

答案 4 :(得分:0)

也许不会迟到回答,但如果你想在这里冲洗每一秒我给你一个样品:

<?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';

答案 5 :(得分:0)

Valentin给了你正确的答案(赞成他/接受他的答案!),但没有解释原因。这是解释:

输出缓冲

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将其关闭/启用。

答案 6 :(得分:0)

好吧,卡洛斯批评我,因为我没有解释我的答案,但他的回答是模糊的...用饼干,图层...... 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

如果您不知道自己有多少层,可以执行以下操作:

while (@ob_end_clean( ));

并清理你可以拥有的每一个垃圾,然后你的代码就可以了。 完成snipp:

<?php
while (@ob_end_clean( ));
while(1) {
    echo "hello";
    flush();
    sleep(1);
}

氰..

答案 7 :(得分:-1)

添加所有其他答案,

要执行异步服务器推送到客户端,您需要使用WebSockets。这是一个广泛的主题,并没有完全标准化,但肯定有这样做的方法。如果您有兴趣搜索PHP Websockets。