Why use output buffering in PHP?

2019-01-17 14:39发布

I have read quite a bit of material on Internet where different authors suggest using output buffering. The funny thing is that most authors argument for its use only because it allows for mixing response headers with actual content. Frankly, I think that responsible web applications should not mix outputting headers and content, and web developers should look for possible logical flaws in their scripts which result in headers being sent after output has been generated. This is my first argument against the ob_* output buffering API. Even for that little convenience you get - mixing headers with output - it is not a good enough reason to use it, unless one needs to hack up scripts fast, which is usually not the goal nor the way in a serious web application.

Also, I think most people dealing with the output buffering API do not think about the fact that even without the explicit output buffering enabled, PHP in combination with the web-server it is plugged into, still does some internal buffering anyway. It is easy to check - do an echo of some short string, sleep for say 10 seconds, and do another echo. Request your script with a browser and watch the blank page pause for 10 seconds, with both lines appearing thereafter. Before some say that it is a rendering artefact, not traffic, tracing the actual traffic between the client and the server shows that the server has generated the Content-Length header with an appropriate value for the entire output - suggesting that the output was not sent progressively with each echo call, but accumulated in some buffer and then sent on script termination. This is one of my gripes with explicit output buffering - why do we need two different output buffer implementations on top of one another? May it be because the internal (inaccessible) PHP/Web-server output buffering is subject to conditions a PHP developer cannot control, and is thus not really usable?

In any case, I for one, start to think one should avoid explicit output buffering (the series of ob_* functions) and rely on the implicit one, assisting it with the good flush function, when necessary. Maybe if there was some guarantee from the web server to actually send output to the client with each echo/print call, then it would be useful to set up explicit buffering - after all one does not want to send response to the client with some 100 byte chunks. But the alternative with two buffers seems like a somewhat useless layer of abstraction.

So, ultimately, do serious web applications need output buffering?

标签: php http
11条回答
疯言疯语
2楼-- · 2019-01-17 15:18

It's useful if you're trying to display a progress bar during a page that takes some time to process. Since PHP code isn't multi-threaded, you can't do this if the processing is hung up doing 1 function.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-17 15:19

i use output buffering for one reason ... it allows me to send a "location" header after i've begun processing the request.

查看更多
太酷不给撩
4楼-- · 2019-01-17 15:20

If you want to output a report to the screen but also send it through email, output buffering lets you not have to repeat the processing to output your report twice.

查看更多
不美不萌又怎样
5楼-- · 2019-01-17 15:22

Ok, here is the real reason : the output is not started until everything is done. Imagine an app which opens an SQL connection and doesn't close it before starting the output. What happens is your script gets a connection, starts outputting, waits for the client to get all it needs then, at the end, closes the connection. Woot, a 2s connection where a 0.3s one would be enough.

Now, if you buffer, your script connects, puts everything in a buffer, disconnects automatically at the end, then starts sending your generated content to the client.

查看更多
祖国的老花朵
6楼-- · 2019-01-17 15:22

Output buffering is critical on IIS, which does no internal buffering of its own. With output buffering turned off, PHP scripts appear to run a lot slower than they do on Apache. Turn it on and they run many times faster.

查看更多
神经病院院长
7楼-- · 2019-01-17 15:23

The most obvious use cases are:

  1. An output filter (eg ob_gzhandler or any number of filters you could devise on your own); I have done this with APIs that only support output (rather than return values) where I wanted to do subsequent parsing with a library like phpQuery.
  2. Maintenance (rather than rewriting) of code written with all the problems you discuss; this includes things like sending headers after output began (credit Don Dickinson) or suppression of certain output that has already been generated.
  3. Staggered output (credit here to Tom and Langdon); note that your tests may have failed because it conflicts with PHP/Apache's default internal buffer, but it is possible to do, it simply requires a certain amount to be flushed before PHP will send anything—PHP will still keep the connection open though.
查看更多
登录 后发表回答