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

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

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

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

谢谢!

【问题讨论】:

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

标签: php sleep php4


【解决方案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,您的浏览器可能正在缓冲它。如果是这种情况,您无法在不切换浏览器的情况下修复它。
    猜你喜欢
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多