tags:

views:

160

answers:

2

Can PHP's ob_start be called more then once?

Sorry if this is a dumb question but I really don't know.

My site is really large (file quantity), its a social network and one of the included files uses ob_start PHP's output buffer for something, i'm not ure someone else started my site a long time ago and now it is mine I need to look into it more to see what it's doing exactly.

Anyways I am wanting to use ob_start ("ob_gzhandler"); to compress CSS files and all files on my site get loaded (included) through the index file so I am wanting to know if I am able to use that even though it is already in use somewhere else in the code?

+3  A: 

Yes, you can call it more than once. It creates a new buffer each time however, so be careful.

From the manual: "Output buffers are stackable, that is, you may call ob_start() while another ob_start() is active. Just make sure that you call ob_end_flush() the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order."

zombat
Thanks and as I mentioned it is already called in my script I need to track down and see if ob_end_flush() is even called, if it isn't what would this cause?
jasondavis
Who knows, might was well try it.
Chacha102
Output buffers are flushed at the end of script execution if you haven't done it yourself with `ob_flush()` or `ob_end_flush()`. However, if you have multiple nested buffers and you expect to process their contents in a particular order, then you might see weird output.
zombat
If you need to know how deeply nested you are, or if you're even in output buffering, the `ob_get_level` function is perfect. http://ca.php.net/ob_get_level
jason
Thanks I tried the ob_get_level and had a value of 1 so I ran ob_get_contents and it appears my whole page, header,body,and, footer are all in the buffer...I'm not sure but I don't think that is a good thing
jasondavis
If you're using ob_gzhandler, that's the only way it can work, as the entire page needs to be buffered to be sent with a `Content-Encoding: gzip` header to the web browser. There are better alternatives to ob_gzhandler because of this. You should look into zlib.output_compression or doing it in apache with mod_deflate.
zombat
ob_gzhandler is perfectly happy if it is installed with a smaller chunk size like ob_start('ob_gzhandler', 512) but you might get better compression results with bigger chunks.
VolkerK
A: 

You say this :

I am wanting to use ob_start ("ob_gzhandler"); to compress CSS files

I would rather serving and compressing JS/CSS (well, static) files is the job of the Web server (ie, Apache), and not PHP.

About that, you can take a look at mod_deflate -- at least, if you are using Apache 2.

all files on my site get loaded (included) through the index file

Is that really necessary ? You're having PHP work with no apparent (?) reason, that way.
(Note that even if CSS/JS files are served through PHP, Apache should be able to compress them with mod_deflate ; same is also true for HTML, JSON, ... btw)

Another advantage of not going through PHP to server those files is that it would be easier to get them served by another server, as your site will grow (if it grows enough, actually) :

  • you could have a bunch of "PHP servers", to process PHP pages
  • and one or two "static-files servers", to server only CSS/JS/images, and lighten the load or your "application servers" ; no need for PHP on these ones ; you could also use something like lighttpd instead of Apache


That being said, ob_start says this :

Output buffers are stackable, that is, you may call ob_start() while another ob_start() is active. Just make sure that you call ob_end_flush() the appropriate number of times. If multiple output callback functions are active, output is being filtered sequentially through each of them in nesting order.

So, I think the answer to your question is "yes" :-)

Pascal MARTIN
Thanks for the info and yes I plan to use lighthttpd for images eventually as for including files through my index, I do this; $pageId['account.profile.settingsBETA'] = 'member/account.profile.settingsBETA.php'; it makes it easy for me to keep track of all the pages, a lot of sites do this, it isn't good?
jasondavis
The index basicly includes a header file, then includes the body from what I posted above this, then includes the footer
jasondavis
OK about that for PHP files ; but you're doing it also for CSS files ? (or I didn't understand what you first said)
Pascal MARTIN