【问题标题】:PHP buffer ob_flush() vs. flush()PHP 缓冲区 ob_flush() 与 flush()
【发布时间】:2011-05-10 15:14:31
【问题描述】:

ob_flush()flush() 之间有什么区别,为什么我必须同时调用这两个?

ob_flush() reference 说:

此函数将发送输出缓冲区的内容(如果有)。

flush() reference 说:

刷新 PHP 的写入缓冲区以及 PHP 正在使用的任何后端(CGI、Web 服务器等)。

但是,它继续说:

[it] 可能无法覆盖您的 Web 服务器的缓冲方案...

所以,在我看来,我可以一直使用ob_flush()。但是,当我这样做时,我会得到奇怪的结果。有人可以简单地解释一下这里发生了什么吗?

【问题讨论】:

    标签: php flush output-buffering


    【解决方案1】:

    ob_flush 发送一个应用程序启动的缓冲区。在任何 PHP 脚本中可能有多个嵌套的ob_start()ob_flush 将当前内容传递给上层。

    PHP 本身可能(自行决定)缓冲输出。这取决于后端。但通常FastCGI 有自己的套接字缓冲区。因此还需要调用flush() 将当前内容发送到Web 服务器。

    现在,Web 服务器本身可能会实现另一个缓冲方案(mod_deflate 或内容过滤器),您对此没有任何影响。但这很少见,因为需要专门配置。

    不管怎样,两者都用。

    【讨论】:

    • 使用 ob_flush 和 flush 并按顺序使用它们。
    • 这个答案中缺少的重要细节是output_buffering 配置选项,其在生产版本的 php.ini 中的默认值为 4096。这意味着当任何 PHP 脚本启动时,前 4096 个字节输出被缓冲(在可使用ob_flush() 刷新的缓冲区中)。这就是为什么必须使用ob_flush()flush() 的原因。通过 php.ini 禁用 output_buffering 或在脚本开头调用 ob_end_clean()ob_end_flush() 消除了这种必要性。
    • 感谢@MarkAmery,但“脚本开头”处的ob_end_clean() 似乎违反直觉。你的意思是我们应该在ob_start() 之后和两次刷新之前包括这个?
    • 好吧,我在脚本的开头有一个ob_start() 和一个ob_end_clean()。然后在脚本期间的任何“回声”之后,我还包括ob_flush(); flush();,我希望在脚本花费时间的同时,到目前为止所做的任何事情都会输出到屏幕上(在浏览器中)。但是直到最后什么都没有。我错过了什么?
    • @KhomNazid 浏览器观察与调试 HTTP 流不同。对不完整 HTML DOM 的增量和延迟输出不太可能是可见的。使用您当前的设置进行一些 CLI 测试。 (然后,并且只有在那时,开始一个不同的问题。)
    【解决方案2】:

    ob_flush 刷新使用ob_start 等函数创建的输出缓冲区

    flush 将 PHP 脚本本身的缓冲输出刷新给调用者

    【讨论】:

      【解决方案3】:

      ob_flush() 是高级刷新。它刷新高级缓冲区并将所有内容放入准备发送的低级内部缓冲区。

      • 请注意,ob_ 系列函数会创建 堆栈 缓冲区,因此如果编写代码是为了利用这一优势,只是盲目地到处写 ob_flush() 确实会给您带来“奇怪的结果”这种堆叠。

      flush() 是低级刷新,指示 PHP 刷新其内部的低级数据缓冲区。

      在此之下,还有套接字层缓冲区;在此之下,有网络层缓冲区。并且,在最低层,沿着数据电缆向下的电子队列。

      【讨论】:

      • 好吧,我在脚本的开头有一个ob_start() 和一个ob_end_clean()。然后在脚本期间的任何“回声”之后,我还包括ob_flush(); flush();,并且我希望在脚本花费时间的同时,到目前为止所做的任何事情都会输出到屏幕上(在浏览器中)。但是直到最后什么都没有。我错过了什么?
      • @KhomNazid 按中间阶段缓冲,例如网络服务器、代理、浏览器...
      【解决方案4】:

      我猜这与您的previous question 有关。使用输出缓冲的显着优势在于它与数据压缩一起使用。如果您不使用ob_gzhandler,则几乎没有什么收获。 flush 将仅提交仍在服务器上的任何输出数据。使用ob_start 及其对应的ob_flushob_end_cleanob_end_flush,任何等待压缩的内容(查看flushob_flush 指代不同的存储桶-ob 将数据发送到flush , flush 将数据发送到浏览器 - 可能不准确,但这就是想法)将被打包并发送到客户端。

      【讨论】:

      • 谢谢,桶类比是一个很好的例子。
      猜你喜欢
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2012-02-29
      • 1970-01-01
      • 2012-01-24
      • 2012-12-24
      相关资源
      最近更新 更多