带有 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 输出的主要内容,如果未能解决你的问题,请参考以下文章