如何运行一个很长的 PHP 脚本并通过 HTTP 不断向浏览器发送更新?

发布于 2024-09-04 16:39:41 字数 70 浏览 10 评论 0原文

如何运行一个很长的 PHP 脚本并通过 HTTP 不断向浏览器发送更新?

与输出缓冲有关,但我不知道具体如何。

How do you run a long PHP script and keep sending updates to the browser via HTTP?

Something to do with output buffering but I don't know exactly how.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

铃予 2024-09-11 16:39:41

输出缓冲正在朝着正确的方向思考,您可以使用 ob_start() 开始输出缓冲,就像在脚本顶部的某个位置(在任何会话之前)使用会话 (session_start) 一样。输出已发送。

然后,您可以使用ob_flush和flush来保持刷新输出。例如,如果您处于 foreach 循环中,并且在每个循环结束时您想要输出新行并等待 1 秒,您就可以这样做。

但还要查看 set_time_limit,否则人们可能会在 30 秒左右后遇到超时。

另一个快速说明是,某些浏览器在实际开始显示输出之前需要最小数量的输出字节。我不确定它有多少字节,我认为大约是 4000。此外,某些浏览器在关闭之前不会渲染某些元素(例如表格)。所以冲洗在那里也不起作用。

Output Buffering is thinking in the right direction, you start output buffering with ob_start() just like you would with sessions (session_start) somewhere in the top of your script, before any output is sent.

Then, you can use ob_flush and flush to keep flushing the output. For example, if you are in a foreach loop and at the end of each loop you want to output the new row and wait 1 second you would can do that.

But also look at set_time_limit, because otherwise people might experience a timeout after 30 seconds or so.

Another quick note, some browsers require a minimum number of bytes of output before they actually start showing it. I'm not sure what amound of bytes it was, I think it was around the 4000. Also, some browsers won't render certain elements (like tables) until they are closed. So flushing won't work there either.

憧憬巴黎街头的黎明 2024-09-11 16:39:41

这看起来像您所追求的:

输出缓冲,一旦准备好,PHP 就会将脚本的输出发送到 Web 服务器 - 这可能是逐行或逐个代码块。

输出缓冲

ob_start()函数用于
创建一个新的输出缓冲区,然后您
可以立即开始写入
正常打印内容。一次
你有一个缓冲区打开,有两个
关闭它的方法:ob_end_flush() 和
ob_end_clean(),两者都结束
缓冲区,但稍微这样做
不同的方式。前者结束
缓冲并将所有数据发送到输出,
后者结束缓冲区而不
有效地将其发送到输出
清除您保存的所有信息
在那里。每一段文字
当输出缓冲器被输出时
open 被放置到该缓冲区中,如下所示
反对发送到输出。
考虑以下脚本:

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

该脚本将输出“首先
buffer”,因为第一个文本是
放入缓冲区然后用
ob_end_flush()。 “在第二个缓冲区中”
但不会被打印出来,因为
它被放入一个缓冲区中
使用 ob_end_clean() 进行清理,而不是
发送到输出。最后,脚本
将打印出“在第三个缓冲区中”
因为PHP会自动刷新打开
当到达末尾时输出缓冲区
一个脚本。

This looks like what you are after:

output buffering, PHP sends the output of your scripts to your web server as soon as it's ready - this might be line by line or code block by code block.

Output Buffering

The ob_start() function is used to
create a new output buffer, and you
can immediately start writing to it by
printing out content as normal. Once
you have a buffer open, there are two
ways to close it: ob_end_flush() and
ob_end_clean(), both of which end the
buffer, but do so in slightly
different ways. The former ends the
buffer and sends all data to output,
and the latter ends the buffer without
sending it to output, effectively
wiping out any information you saved
in there. Every piece of text
outputted while an output buffer is
open is placed into that buffer as
opposed to being sent to output.
Consider the following script:

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

That script will output "In first
buffer" because the first text is
placed into a buffer then flushed with
ob_end_flush(). The "In second buffer"
won't be printed out, though, because
it's placed into a buffer which is
cleaned using ob_end_clean() and not
sent to output. Finally, the script
will print out "In third buffer"
because PHP automatically flushes open
output buffers when it reaches the end
of a script.

無心 2024-09-11 16:39:41

您还可以有一种后台任务,以及一个为您提供进度的界面。

例如,一个名为 job.php

<?php
    for ($i=0; $i<100; ++$i)
    {
       store($i);
       // long stuff
       sleep(42);
    }
?>

和progress.php 的

<?php
      return get($i);
?>

页面然后一些ajax 调用progress.php?task=mytaskid 并更新GUI。我见过这种用于“大”文件上传的方法,并发现它很棒。

编辑:抱歉,这并不能完全回答最初的问题。

You can also have a kind of background task, and an interface giving you the progress rate.

for instance, a page called job.php

<?php
    for ($i=0; $i<100; ++$i)
    {
       store($i);
       // long stuff
       sleep(42);
    }
?>

and progress.php

<?php
      return get($i);
?>

Then some ajax calls to progress.php?task=mytaskid and update the GUI. I have seen such method for a "big" file upload and found it great.

Edit: sorry, this doesn't exactly respond the initial question.

め可乐爱微笑 2024-09-11 16:39:41
<?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
}
?>
<?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
}
?>
如果没结果 2024-09-11 16:39:41

我使用简单的 HTTP 输出更新页面,以使其正常工作:

  • 确保关闭 中的所有打开元素 - 否则它不会显示
  • Enclose outputted text in an element (such as作为

    )

  • 使用输出缓冲 &正常刷新
  • 在 Firefox 3 上测试

这是我的代码:

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();
}

I got it the page updating using simple HTTP outputting, to make it work:

  • Ensure that you close any open elements within <body> - else it won't display
  • Enclose outputted text in an element (such as a <p>)
  • Use output buffering & normal flushing
  • Tested on Firefox 3

Here is my code:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文