15

I use output buffering for gzip compression and access to what was put out before in a PHP script:

if(!ob_start("ob_gzhandler")) ob_start();

Now if that script gets included in another script where ob_start() already is in use I get a warning:

Warning: ob_start() [ref.outcontrol]: output handler 'ob_gzhandler' cannot be used twice in filename on line n

So I'd like to test whether ob_start() has already been called. I think ob_get_status() should be what I need but what is the best way to use it in testing for this?

kguest
  • 3,804
  • 3
  • 29
  • 31
C.O.
  • 2,281
  • 6
  • 28
  • 51

4 Answers4

18

ob_get_level returns the number of active output control handlers and ob_list_handlers returns a lift of those handlers. So you could do this:

if (!in_array('ob_gzhandler', ob_list_handlers())) {
    ob_start('ob_gzhandler');
} else {
    ob_start();
}

Although in general you can call ob_start any number of times you want, using ob_gzhandler as handler cannot as you would compress already compressed data.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • I was irritated by the [comment on the manual](http://www.php.net/manual/en/function.ob-get-level.php) that claims "Sometimes, ob_get_level() may be off by 1 because at the start of the script, it will return 1 even if ob_start() has never been called". So is this a reliable way to tell? – C.O. May 15 '11 at 18:49
  • @C.O.: That is probably be due to [output_buffering](http://php.net/manual/en/outcontrol.configuration.php#ini.output-buffering): “If [output_buffering](http://php.net/manual/en/outcontrol.configuration.php#ini.output-buffering) is enabled or an anonymous function was used with `ob_start()`, `ob_list_handlers()` will return "`default output handler`".” – Gumbo May 15 '11 at 18:51
11
if (ob_get_level())
    echo "ob already started";
AndersTornkvist
  • 2,610
  • 20
  • 38
  • I was irritated by the [comment on the manual](http://www.php.net/manual/en/function.ob-get-level.php) that claims "Sometimes, ob_get_level() may be off by 1 because at the start of the script, it will return 1 even if ob_start() has never been called". So is this a reliable way to tell? – C.O. May 15 '11 at 18:45
  • @C.O. I've read the comment, but this is not true. It will return 0 even if called at the start of the script. You could have a look at my example: http://codepad.org/SrZ4YdQn – AndersTornkvist May 15 '11 at 18:51
  • 1
    It **is** true. Ran into it last week on a shared server. Best way to handle it is to start your code with `if(ob_get_level())ob_end_clean();` before `ob_start()` – Michel Sep 23 '13 at 15:02
  • @Michel That is probably due to server starting output buffering automatically. – AndersTornkvist Feb 15 '14 at 13:38
6

General:

if (ob_get_status())  {
  // ob started
}

More specific

$status = ob_get_status();
if ($status['name']=='ob_gzhandler') {
 // ob named ob_gzhandler started
}
CrayonViolent
  • 32,111
  • 5
  • 56
  • 79
  • That was what I was looking for. Thanks. I'll use Gumbo's suggestion above I think. – C.O. May 15 '11 at 18:51
2

What about using it this way?

if (ob_get_level() == 0) ob_start();

Henrik P. Hessel
  • 36,243
  • 17
  • 80
  • 100
  • I was irritated by the [comment on the manual](http://www.php.net/manual/en/function.ob-get-level.php) that claims "Sometimes, ob_get_level() may be off by 1 because at the start of the script, it will return 1 even if ob_start() has never been called". So is this a reliable way to tell? – C.O. May 15 '11 at 18:48
  • At least there is no bug report for this kind of problem. Might be the commenters fault. http://bugs.php.net/search.php?cmd=display&search_for=ob_get_level&x=0&y=0 – Henrik P. Hessel May 15 '11 at 18:51
  • Yes probably but that comment was what led me to start this question. I wanted to get some opinions. So thanks. – C.O. May 15 '11 at 19:07