# Revisiting output control code

- Thread: https://externals.io/message/22029
- Original archive: https://news-web.php.net/php.internals/22029
- Started by Michael Wallner on 2006-02-27T11:51:31+00:00
- Messages: 13
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #22029 — Michael Wallner — 2006-02-27T11:51:31+00:00

URL: https://externals.io/message/22029#22029

Hi,

I'd like to suggest that we revisit the output control (output buffering) code base.
The current implementation uses way too less commands to do too many different
operations, which almost always causes problems with output handlers that need
to maintain a state or context.

Short example:
 `ob_clean()` causes havoc with ext/zlib ob handlers and any handlers found in pecl/http.
 `ob_clean()` passes currently buffered input through the handler and discards it, which
means in the case of the gz handler that the gzip/zlib header bytes (and more) are
missing from the sent data.

Things I think that should come with the new code:
	Support for an opaque handler context, which will be passed to the handler.
	More distinct commands like FLUSH, RESTART and/or CLEAN.

Thoughts/comments/flames?

Regards,
-- 
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz

---

## #22030 — Jared Williams — 2006-02-27T12:49:29+00:00

URL: https://externals.io/message/22029#22030 · In reply to: #22029

> I'd like to suggest that we revisit the output control 
> (output buffering) code base.
> The current implementation uses way too less commands to do 
> too many different operations, which almost always causes 
> problems with output handlers that need to maintain a state 
> or context.
> 
> Short example:
> `ob_clean()` causes havoc with ext/zlib ob handlers and any 
> handlers found in pecl/http.
> `ob_clean()` passes currently buffered input through the 
> handler and discards it, which means in the case of the gz 
> handler that the gzip/zlib header bytes (and more) are 
> missing from the sent data.
> 
> Things I think that should come with the new code:
> 	Support for an opaque handler context, which will be 
> passed to the handler.
> 	More distinct commands like FLUSH, RESTART and/or CLEAN.
> Thoughts/comments/flames?

Sounds like should be built upon/replaced with streams.

Jared

---

## #22033 — Jasper Bryant-Greene — 2006-02-27T20:48:59+00:00

URL: https://externals.io/message/22029#22033 · In reply to: #22029

Michael Wallner wrote:
> I'd like to suggest that we revisit the output control (output 
> buffering) code base.

On a semi-related note, I'd like to see the docs mention that print_r 
and var_export (with the second parameter set to TRUE), and 
debug_print_backtrace, internally use the output buffering code to 
capture their output, meaning that using them inside an output buffering 
handler will always cause a fatal error.

Alternatively, I'd like to see these functions *not* use the ob 
functions to do their work. I realise the former is probably easier though.

Jasper

---

## #22036 — Friedhelm Betz — 2006-02-28T13:46:53+00:00

URL: https://externals.io/message/22029#22036 · In reply to: #22033

Jasper Bryant-Greene wrote:
> Michael Wallner wrote:
> > […]
> 
> On a semi-related note, I'd like to see the docs mention that print_r 
> and var_export (with the second parameter set to TRUE), and 
> debug_print_backtrace, internally use the output buffering code to 
> capture their output, meaning that using them inside an output buffering 
> handler will always cause a fatal error.

Open a bug report at bugs.php.net "Documentation Problem"?

Friedhelm

---

## #22037 — Zeev Suraski — 2006-02-28T16:45:27+00:00

URL: https://externals.io/message/22029#22037 · In reply to: #22029

At 13:51 27/02/2006, Michael Wallner wrote:
>Hi,
>
>I'd like to suggest that we revisit the output control (output 
>buffering) code base.
>The current implementation uses way too less commands to do too many different
>operations, which almost always causes problems with output handlers that need
>to maintain a state or context.
>
>Short example:
>ob_clean() causes havoc with ext/zlib ob handlers and any handlers 
>found in pecl/http.
>ob_clean() passes currently buffered input through the handler and 
>discards it, which
>means in the case of the gz handler that the gzip/zlib header bytes 
>(and more) are
>missing from the sent data.

Why would you call `ob_end_clean()` in those cases?  It seems to me 
that what you want to do is actually create another layer of output 
buffering on top of those custom output handlers, if you want to 
control the contents itself.  If you think of custom output buffers 
as a filter, then it makes perfect sense that calling `ob_end_clean()` 
would cause problems.  If you do it in another layer of output 
buffering, then the format of zlib/gz will remain intact without any problems.

I'm also not sure about what you're saying with the gzip/zlib headers 
missing - do you mean the footers?

Zeev

---

## #22038 — Hannes Magnusson — 2006-02-28T16:58:21+00:00

URL: https://externals.io/message/22029#22038 · In reply to: #22037

> I'm also not sure about what you're saying with the gzip/zlib headers
> missing - do you mean the footers?
>
Refering to http://bugs.php.net/bug.php?id=36514 I belive

- Hannes

---

## #22039 — Zeev Suraski — 2006-02-28T17:07:25+00:00

URL: https://externals.io/message/22029#22039 · In reply to: #22038

I misread the post, I thought we were talking about 
 `ob_end_clean()`.  Yes, `ob_clean()` may cause this problem to happen, 
but again, the right approach would be having an 'applicative' output 
buffer on top of the gzip output buffer.  We can look into letting 
output handlers denote that `ob_clean()` is not allowed on them.

Zeev


At 18:58 28/02/2006, Hannes Magnusson wrote:
>
> > […]
>Refering to http://bugs.php.net/bug.php?id=36514 I belive
>
>- Hannes

---

## #22087 — Michael Wallner — 2006-03-02T18:24:09+00:00

URL: https://externals.io/message/22029#22087 · In reply to: #22039

Zeev Suraski wrote:
> I misread the post, I thought we were talking about `ob_end_clean()`.  
> Yes, `ob_clean()` may cause this problem to happen, but again, the right 
> approach would be having an 'applicative' output buffer on top of the 
> gzip output buffer.  We can look into letting output handlers denote 
> that `ob_clean()` is not allowed on them.

This would be in deed an option.

If you still consider a rather fundamental enhancement of the output control
code, please take a look at my initial try.  It already /seems to work/ but
probably misses a few things.  I must admit though, that I did not fully
understand the current implementation.

Considered issues:
	Support of contexts for internal output handlers that had to maintain
it in a global variable, which caused those handlers being only usable
once;  while often natural, like for the gz handler, still a limitation.
	Conflict handlers, so that one doesn't need to incorporate that
code directly in output.c, but register them from within an extension etc.
	Distinct ops, like FLUSH and CLEAN to signal the handler what's
going on; there should also be a possibility to change the abilities of
a handler in runtime, which is not implemented yet, eg. the gz handler
could remove the CLEANABLE and REMOVABLE flags when the first output
did pass through it.

Unfortunately I don't know which version of re2c Ilia used to generate
the url scanner, so a big part of the diff is pretty useless; note that
the patch is against current 5_1 CVS.

http://dev.iworks.at/PATCHES/ob.patch.txt.gz
http://dev.iworks.at/PATCHES/output.c.txt
http://dev.iworks.at/PATCHES/php_output.h.txt

Thanks a lot,
-- 
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz

---

## #22108 — Marcus Boerger — 2006-03-04T15:09:56+00:00

URL: https://externals.io/message/22029#22108 · In reply to: #22087

Hello Michael,

  i never liked the output buffering code much becuase i find it too complex
and too much stuff there is interacting in a way one cannot understand
easily. If there is a simple solution at hand that solves some problem and
that thing disables selective features by just disallowing invocation of
certain control function i'd never be against. If it fixed a problem at hand
i'd be all for it of course. Anyway that would only increase the complexity.
So yes a redisign wouldn't hurt. And if that means we could get rid of
strange side effects of stuff that is imo abusing the output buffering by
using a temporary output buffer i'd appreciate it. However as said on irc i
am not sure it's worth the effort and cannot make out how much new problems
we'd head to. That you even provide a nice looking patch here shows that you
are confident with the idea and agree to do the work.

best regards
marcus

Thursday, March 2, 2006, 7:24:09 PM, you wrote:

> Zeev Suraski wrote:
> > […]

> This would be in deed an option.

> If you still consider a rather fundamental enhancement of the output control
> code, please take a look at my initial try.  It already /seems to work/ but
> probably misses a few things.  I must admit though, that I did not fully
> understand the current implementation.

> Considered issues:
>         Support of contexts for internal output handlers that had to maintain
> it in a global variable, which caused those handlers being only usable
> once;  while often natural, like for the gz handler, still a limitation.
>         Conflict handlers, so that one doesn't need to incorporate that
> code directly in output.c, but register them from within an extension etc.
>         Distinct ops, like FLUSH and CLEAN to signal the handler what's
> going on; there should also be a possibility to change the abilities of
> a handler in runtime, which is not implemented yet, eg. the gz handler
> could remove the CLEANABLE and REMOVABLE flags when the first output
> did pass through it.

> Unfortunately I don't know which version of re2c Ilia used to generate
> the url scanner, so a big part of the diff is pretty useless; note that
> the patch is against current 5_1 CVS.

> http://dev.iworks.at/PATCHES/ob.patch.txt.gz
> http://dev.iworks.at/PATCHES/output.c.txt
> http://dev.iworks.at/PATCHES/php_output.h.txt

> Thanks a lot,
> -- 
> Michael - <mike(@)php.net>
> http://dev.iworks.at/ext-http/http-functions.html.gz




Best regards,
 Marcus

---

## #22138 — Michael Wallner — 2006-03-06T14:31:38+00:00

URL: https://externals.io/message/22029#22138 · In reply to: #22108

Marcus Boerger wrote:

>   i never liked the output buffering code much becuase i find it too complex
> and too much stuff there is interacting in a way one cannot understand
> easily.
[...]
> So yes a redisign wouldn't hurt. And if that means we could get rid of
> strange side effects of stuff that is imo abusing the output buffering by
> using a temporary output buffer i'd appreciate it.
[...]
> That you even provide a nice looking patch here shows that you
> are confident with the idea and agree to do the work.

Thanks for your response, Marcus.
I hope others will find the time for a quick review and statement, too?

> > […]

Thank you,
-- 
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz

---

## #22140 — Michael Wallner — 2006-03-06T16:41:41+00:00

URL: https://externals.io/message/22029#22140 · In reply to: #22108

Marcus Boerger wrote:

> And if that means we could get rid of
> strange side effects of stuff that is imo abusing the output buffering by
> using a temporary output buffer i'd appreciate it. 

I guess you mean `var_dump()` and friends?
I didn't touch anything beneath Zend/ though.

Regards,
-- 
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz

---

## #22161 — Xuefer — 2006-03-07T03:12:10+00:00

URL: https://externals.io/message/22029#22161 · In reply to: #22140

is there any chance that a buffer in output buffer will be supported?
supposing u're implementing "send the whole page in html to friends"
function. using smarty as email template.
if (isset($_GET['send_html_to'])) {
ob_start('send_as_html');
}
function send_as_html($content)
{
$tpl = new Smarty("html_email");
prepair_html($content);
$tpl->assign($html, $content);
$content = $tpl->fetch(); <- this use ob_start to catch all output
from the compiled template
}

q: why not do "$content = `ob_get_clean()` and $tpl->fetch() after it"
in this case?
a: because i can't put `ob_get_clean()` code in all the php pages.
q: but u can do ob_start('send_as_html') in all pages? because i can
put it in a common lib that every page include.

---

## #22245 — Michael Wallner — 2006-03-08T12:03:11+00:00

URL: https://externals.io/message/22029#22245 · In reply to: #22161

Xuefer wrote:
> is there any chance that a buffer in output buffer will be supported?

Nope, as this can cause all sorts of evil things.

Regards,
-- 
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz
