【问题标题】:Echo messages while php script still executes在 php 脚本仍在执行时回显消息
【发布时间】:2011-01-12 14:22:12
【问题描述】:

我有一个使用 cURL 的 php 脚本,执行大约需要 10-15 分钟。它的作用是解析大约 1000 个页面以查找特定匹配项,并且在整个脚本中我都回显了诊断消息,例如“转到下一页”、“找到匹配项”、“加载页面错误”……它现在的工作方式(以及正常的方式)是它执行了大约 10 分钟,然后才吐出我所有的自定义消息。 我希望能够在这些消息发生时显示这些消息,而不是在脚本执行完成时显示。我在想像 AJAX 这样的东西会做到这一点,但不确定它是如何工作的。非常感谢任何提示。谢谢。

【问题讨论】:

  • 类似于this question
  • 另一种简单的情况是从命令行执行脚本,这样您就可以实时获得回声。

标签: php curl messages


【解决方案1】:

所以,这是一篇旧帖子,但我找到了解决方案。因为我也必须做同样的事情,所以在脚本仍在运行时输出。这里没有任何答案有帮助。 首先,我使用 Win32 服务器(生产)和 XAMPP 作为本地测试。这个例子只是一个概念证明,可以随意修改。

<?php 
ob_implicit_flush(true);
for($i=1; $i<=10; $i++){
echo "$i ...<br>";
for($k = 0; $k < 40000; $k++) echo ' ';
sleep(1);
}
?>

因此,我们以隐式方式打开输出缓冲区。然后我们创建一个演示循环,从 1 计数到 10,并在处理这些值时显示这些值。第二个循环将填充浏览器缓冲区。最后,为了检查一切是否正常,我们休眠 1 秒钟。否则脚本将运行得太快,我们无法知道我们是否达到了目标。 希望这会有所帮助!

【讨论】:

    【解决方案2】:

    您可以创建一个临时表。

    PHP 脚本可以将它们存储到数据库表(可能是内存表以提高性能)中,而不是回显消息。

    然后您可以使用 ajax 定期轮询单独的 PHP 脚本,该脚本将查询表,并将任何新消息返回给客户端。

    【讨论】:

    • 同意。冲洗不会 100% 的时间起作用。需要 Ajax。
    • 难道没有类似推送的解决方案(而不是轮询)吗?
    【解决方案3】:

    使用flush 通过刷新输出缓冲区立即将输出发送到浏览器。

    echo "foo";
    flush();
    echo "bar";
    flush();
    

    【讨论】:

    • Flush 不保证适用于所有浏览器/平台/配置
    【解决方案4】:

    实际上,您正在寻找 flushob_flush 之类的东西,但请记住,有很多因素会阻止您的输出在发生时被刷新。

    您会从flush 文档中获得:

    一些服务器,尤其是在 Win32 上,仍然会缓冲脚本的输出,直到它在将结果传输到浏览器之前终止。

    像 mod_gzip 这样的 Apache 服务器模块可能会自己做缓冲,这会导致 flush() 不会导致数据立即发送到客户端。

    【讨论】:

    • 你说得很好,直到脚本完成我在Win32平台上工作,然后我会把它放到unix上
    【解决方案5】:

    我在每个echo 之后使用@ob_flush()。在此示例中,PHP_EOL$string 之后创建一个新行

    function output($string){
        echo $string.PHP_EOL;
        @ob_flush();
    }
    

    【讨论】:

      【解决方案6】:

      基本上,让您的脚本将 HTML 输出写入临时日志文件。然后使用 ajax 使用临时日志文件定期更新最终用户的浏览器。 jQuery 会快速解决这个问题。

      Ajax 是让它在所有浏览器上工作的唯一有保证的方法。这是来自 PHP 的刷新页面的引用。

      flush() 可能无法覆盖 您网站的缓冲方案 服务器,它对任何服务器都没有影响 浏览器中的客户端缓冲。 它也不会影响 PHP 的用户空间 输出缓冲机制。这意味着 你将不得不同时调用 ob_flush() 和 flush() 刷新 ob 输出 如果你正在使用这些缓冲区。

      【讨论】:

      • 如果有 1000 个用户同时使用不同的参数访问页面怎么办? ,你需要写 1000 个文件,我不认为这是一个选项。
      • 您可以轻松地在 PHP 中创建临时文件。它与 1000 个用户将内容插入 mysql 数据库基本相同。哎呀,使用,mysql。如果不止一个人使用它,只需将日志存储在某个地方并将其绑定到该会话。我感觉这是一个供一个人使用的后端脚本。
      【解决方案7】:

      听起来就像你打开了output buffering

      调用ob_end_flush() 将打印缓冲区中的当前内容,并在脚本执行的其余部分关闭缓冲区。

      【讨论】:

        【解决方案8】:

        您可以使用 flush() 函数将缓冲区的所有内容发送到客户端。 http://php.net/manual/fr/function.flush.php

        【讨论】:

          【解决方案9】:

          flushob_flush可以同时使用,提醒设置内容类型头:

          <?php
          header( 'Content-type: text/html; charset=utf-8' );
          for( $i = 0 ; $i < 10 ; $i++ ){
              echo $i . '<br>';
              flush();
              ob_flush();
              sleep(1);
          }
          

          来源:dermeister php.net ob_flush 页面中的注释。

          在 Firefox 42.0 和 Chrome 46.0 上测试

          【讨论】:

            猜你喜欢
            • 2011-07-21
            • 2021-09-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-06-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多