带有 sleep() 的 php 输出

Posted

技术标签:

【中文标题】带有 sleep() 的 php 输出【英文标题】:php output with sleep() 【发布时间】:2011-03-27 14:10:40 【问题描述】:

基本上,我试图每秒运行一个循环,持续 25 秒。

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

问题是它在完全完成之前不会输出,所以在循环继续 25 次之后。有没有办法做到这一点,所以它会在每次睡眠前输出?而不是等到整个循环完成?

谢谢!

【问题讨论】:

您的浏览器和内容是什么?一些浏览器在遇到结束标记之前不会呈现 html。如果您想要“实时更新”内容,纯文本可能是更好的选择。 这似乎是一个在客户端处理得更好的问题。您可以每秒使用 AJAX 从服务器获取数据。 这绝对不是您在服务器上尝试的方式.. 在浏览器中使用一些 ajax 和 setTimeout 等.. 【参考方案1】:

您想要实现的是从 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 模块会立即刷新它。如果你没有输出缓冲,或者像 mod_gzip 这样的 Apache 模块,那么它应该立即输出到用户的浏览器。更重要的是,在默认配置下,你可以让你的 PHP 脚本运行任意长的时间(在 PHP 中使用 set_time_limit()),当然它会消耗一些内存。

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

【讨论】:

【参考方案2】:

我只是从初学者的角度解决了同样的问题,并想出了这个简单的脚本,它可以满足你的需求。

<?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())。希望对您有所帮助。

【讨论】:

我已经尝试了很多关于输出缓冲的不同建议,这是唯一真正有效的!很惊讶这是第一个引用填充输出长度的方法。【参考方案3】:

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

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

编辑:

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

此策略的另一个问题是它使 PHP proc 被其他请求阻塞。这可能会导致请求堆积。

【讨论】:

嗯.. 似乎没有成功.. 还尝试了 w/ob_start()、ob_flush() 和 flush() 通常ob_end_flush()(跳过ob_start())和flush()的组合可以做到这一点。你和运行 PHP 的服务器之间有代理服务器吗? 为我工作通过命令行运行,但不是浏览器......在我在 sleep(1) 后放置分号后 @Dave 尝试通过命令行使用 curl,您的浏览器可能正在缓冲它。如果是这种情况,您无法在不切换浏览器的情况下修复它。

以上是关于带有 sleep() 的 php 输出的主要内容,如果未能解决你的问题,请参考以下文章

php sleep()的实时输出打印,清除ob缓冲区

php sleep

php输出日志的实现

PHP即时实时输出内容

如何在发生时从 php 获取实时输出?

php Nginx实时输出数据到浏览器