php输出与sleep()

时间:2010-08-10 00:42:33

标签: php sleep php4

我试图基本上每秒运行一次循环25秒。

for($i = 0; $i <= 25; $i += 1){ 
    echo $i;
    sleep(1)
}

事情是它完全没有输出,所以循环继续25次。有没有办法这样做,所以它会在每次睡眠前输出?而不是等到完整循环完成?

谢谢!

3 个答案:

答案 0 :(得分:8)

您要实现的是从PHP向浏览器增量输出。

这是否可实现取决于您的服务器以及您如何调用PHP。

FastCGI下的PHP

当PHP在 FastCGI 下而不是作为Apache模块运行时,你可能更容易遇到这种问题,因为服务器和PHP进程之间的耦合不是紧密耦合。一旦数据离开PHP进程,FastCGI通信就使用输出缓冲,只有在请求完全完成后才将输出发送到浏览器,或者此缓冲区已填满。除此之外,PHP进程往往会在一定时间后终止,以避免让任何一个运行太长时间。

也就是说,ob_end_flush()(或ob_flush())和flush()的组合仍然会导致PHP请求清除下游缓冲区,因此这可能仍然有效。您可能还需要调查是否需要延长PHP脚本的时间限制。

mod_php下的PHP

如果您正在使用mod_php,则可以逐步向浏览器写入。使用flush()命令确保PHP模块立即刷新它。如果你没有输出缓冲,或某些Apache模块,如mod_gzip,那么它应该立即发送到用户的浏览器。更重要的是,您可以根据需要保持PHP脚本运行(在PHP中使用set_time_limit()),在默认配置下,当然它会占用一些内存。

在下载一定数量的页面之前,某些浏览器可能会遇到问题,这些浏览器无法开始呈现页面。某些版本的IE可能会等待1KB。我发现Chrome可以等待更多。许多人通过添加填充来解决这个问题,例如在文档顶部长1或2 KB的注释。

答案 1 :(得分:4)

调用flush将强制PHP在继续之前将所有输出缓冲区推送到客户端。

for($i = 0; $i <= 25; $i += 1){ 
    echo $i;
    flush();
    sleep(1);
}

编辑:

在我的lighttpd服务器上测试后,我注意到它以4096个字符的块缓冲输出,我认为其他浏览器可能有类似的缓冲方案。 GZIP也可以完全阻止flush。遗憾的是,由于HTTP的性质,无法测试它是否正常工作。

此策略的另一个问题是它将PHP proc阻止其他请求。这可能会导致请求堆积起来。

答案 2 :(得分:4)

我刚刚从初学者的角度来看待这个相同的问题,并提出了这个可以做你想做的简单脚本。

<?PHP
ob_start();
$buffer = str_repeat(" ", 4096)."\r\n<span></span>\r\n";

for ($i=0; $i<25; $i++) {
  echo $buffer.$i;
  ob_flush();
  flush();
  sleep(1);
}

ob_end_flush();
?>

您可能会问的问题可能是here(约\r\n)和here(约ob_flush())。希望能帮到你。