PHP buffer ob_flush() vs. flush()
What's the difference between ob_flush()
and flush()
and why must I call both?
The ob_flush()
reference says:
This function will send the contents of the output buffer (if any).
The flush()
reference says:
Flushes the write buffers 开发者_开发知识库of PHP and whatever backend PHP is using (CGI, a web server, etc).
However, it continues to say:
[it] may not be able to override the buffering scheme of your web server…
So, seems to me that I could just use ob_flush()
all of the time. However, I get strange results when I do that. Could someone explain in simple terms what's going on here?
ob_flush
sends an application-initiated buffer. There may be multiple nested ob_start()
's in any PHP script. ob_flush
passes the current content to the upper layer.
PHP itself might (at its own discretion) buffer output. This depends on the back-end. But usually FastCGI
has a socket buffer on its own. Therefore flush()
needs to be invoked as well to send the current content to the web server.
And now the web server might itself implement another buffering scheme (mod_deflate
or content filter), which you have no influence over. But this is seldom, as it needs to be configured specifically.
Anyway, use both.
ob_flush
flushes output buffers you created with a function like ob_start
flush
flushes buffered output of the PHP script itself to its caller
ob_flush()
is a high-level flush. It flushes high-level buffers and puts all content in the low-level, internal buffers ready to send.
- Note that the
ob_
family of functions create stacks of buffers, so just blindly writingob_flush()
everywhere is indeed going to give you "strange results" if the code was written to take advantage of this stacking.
flush()
is a low-level flush, instructing PHP to flush its internal, low-level data buffers.
Below that still, there will be socket-layer buffers; below that, there are network-layer buffers. And, at the lowest level, the queue of electrons going down the data cable.
I guess this is in relation to your previous question. The significant advantage of using output buffering is when it's used alongside data compression. If you're not using ob_gzhandler
, there's little to gain. flush
alone will just commit whatever output data is still on the server. With ob_start
and its counterparts ob_flush
, ob_end_clean
and ob_end_flush
, whatever is waiting to be compressed (look at flush
and ob_flush
as referring to different buckets - ob
sends data to flush
, flush
sends data to browser - may not be accurate but that's the idea) will be wrapped up and sent to the client.
精彩评论