PHP缓冲区ob_flush()与flush()


79

什么之间的区别ob_flush(),并flush()和我为什么一定要同时调用?

ob_flush()参考说:

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

flush()参考说:

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

但是,它继续说:

[它]可能无法覆盖Web服务器的缓冲方案…

因此,在我看来,我可以一直使用ob_flush()所有时间。但是,这样做会得到奇怪的结果。有人可以简单地解释一下这是怎么回事吗?

Answers:


75

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

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

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

无论如何,请同时使用两者。


11
使用ob_flush和flush并按顺序使用它们。
Robino 2013年

17
该答案缺少的重要细节是output_buffering配置选项,其在生产版本的php.ini中的默认值为4096。这意味着当任何PHP脚本启动时,输出的前4096个字节将被缓冲(在可刷新的缓冲区中ob_flush())。这就是为什么必须使用ob_flush()和的原因flush()output_buffering通过php.ini禁用ob_end_clean()ob_end_flush()在脚本开始处调用或可以消除此必要。
Mark Amery 2014年

感谢@MarkAmery,但ob_end_clean()在“脚本开始”时似乎违反直觉。您的意思是我们应该ob_start()在两次冲洗之后和之前将其包括在内吗?
纳姆

好吧,我在脚本的开头有一个ob_start()和一个ob_end_clean()。然后,在脚本执行过程中出现任何“回声”之后,我还将包括ob_flush(); flush();,并且我希望在脚本花费时间的同时,到目前为止所做的任何事情都会在屏幕上(在浏览器中)输出。但是直到最后都没有解决。我想念什么?
卡姆·纳兹

1
@KhomNazid浏览器的观察与调试HTTP流不同。输出到不完整的HTML DOM的增量和延迟输出不太可能看到。使用当前设置进行一些CLI测试。(然后,直到那时,才对此提出一个不同的问题。)
mario

33

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

flush 将PHP脚本本身的缓冲输出刷新到其调用方


25

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

  • 请注意,ob_函数家族会创建缓冲区堆栈,因此,ob_flush()如果编写代码来利用此堆栈,那么盲目地在所有地方编写确实会给您“奇怪的结果”。

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

在此之下,仍将有套接字层缓冲区。在此之下,有网络层缓冲区。而且,在最低层次上,电子队列沿着数据电缆传输。


好吧,我在脚本的开头有一个ob_start()和一个ob_end_clean()。然后,在脚本执行过程中出现任何“回声”之后,我还将包括ob_flush(); flush();,并且我希望在脚本花费时间的同时,到目前为止所做的任何事情都会在屏幕上(在浏览器中)输出。但是直到最后都没有解决。我想念什么?
卡姆·纳兹

@KhomNazid由中间阶段缓冲,例如Web服务器,代理,您的浏览器...
轨道中的Lightness

11

我想这与您先前的问题有关。使用输出缓冲的显着优势是与数据压缩一起使用。如果您不使用ob_gzhandler,将无济于事。flush一个人就可以提交仍然在服务器上的所有输出数据。凭借ob_start其同行ob_flushob_end_clean并且ob_end_flush,无论是等待被压缩(看看flush,并ob_flush为涉及不同的桶-ob将数据发送到flushflush将数据发送到浏览器-可能不准确,但是这想法)将被包装起来,发送到客户端。


谢谢,桶类比是一个很好的例子。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.