如何运行较长的 PHP 脚本并通过 HTTP 不断向浏览器发送更新?
与输出缓冲有关,但我不知道具体如何。
输出缓冲的思考方向是正确的,在发送任何输出之前,您ob_start()
可以像在脚本顶部的某个位置使用会话 ( ) 一样开始输出缓冲。session_start
然后,您可以使用ob_flush
andflush
来保持刷新输出。例如,如果您在一个foreach
循环中并且在每个循环结束时您想要输出新行并等待 1 秒,您可以这样做。
但也要看看set_time_limit
,因为否则人们可能会在 30 秒左右后遇到超时。
另一个快速说明,一些浏览器在实际开始显示之前需要最少的输出字节数。我不确定它是多少字节,我认为它在 4000 左右。此外,某些浏览器在关闭之前不会呈现某些元素(如表格)。所以冲洗在那里也不起作用。
这看起来像你所追求的:
输出缓冲,PHP 将脚本的输出在准备好后立即发送到您的 Web 服务器——这可能是逐行或逐个代码块的。
ob_start() 函数用于创建一个新的输出缓冲区,您可以通过正常打印内容立即开始写入它。一旦你打开了一个缓冲区,有两种方法可以关闭它:ob_end_flush() 和 ob_end_clean(),这两种方法都会结束缓冲区,但方式略有不同。前者结束缓冲区并将所有数据发送到输出,后者结束缓冲区而不将其发送到输出,有效地清除了您保存在其中的任何信息。在输出缓冲区打开时输出的每一段文本都被放入该缓冲区,而不是发送到输出。考虑以下脚本:
<?php
ob_start();
print "In first buffer!\n";
ob_end_flush();
ob_start();
print "In second buffer!\n";
ob_end_clean();
ob_start();
print "In third buffer!\n";
?>
该脚本将输出“在第一个缓冲区中”,因为第一个文本被放入缓冲区,然后用 ob_end_flush() 刷新。但是,“在第二个缓冲区中”不会被打印出来,因为它被放置在一个使用 ob_end_clean() 清理的缓冲区中,而不是发送到输出。最后,脚本将打印出“在第三个缓冲区中”,因为 PHP 在到达脚本末尾时会自动刷新打开的输出缓冲区。
您还可以拥有一种后台任务,以及一个为您提供进度的界面。
例如,一个名为 job.php 的页面
<?php
for ($i=0; $i<100; ++$i)
{
store($i);
// long stuff
sleep(42);
}
?>
和progress.php
<?php
return get($i);
?>
然后对progress.php?task=mytaskid 进行一些ajax 调用并更新GUI。我见过这种“大”文件上传的方法,发现它很棒。
编辑:抱歉,这并不能完全回答最初的问题。
<?php
# try this...
for (;;) {
echo time() . '<br>';
ob_flush(); # http://php.net/ob_flush
flush(); # http://php.net/flush
sleep(1); # http://php.net/sleep
}
?>
我使用简单的 HTTP 输出来更新页面,使其工作:
<body>
- 否则不会显示<p>
)这是我的代码:
for ($nc=0; $nc<10; $nc++){
// delay just to test
sleep(1);
// send message to browser
ob_end_clean();
ob_start();
echo "<p>Update ".$nc."</p>";
ob_end_flush();
flush();
}