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
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
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
Jasper Bryant-Greene wrote:
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.
Open a bug report at bugs.php.net "Documentation Problem"?
Friedhelm
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
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
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:
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
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
thatob_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
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:
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
thatob_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
Best regards,
Marcus
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?
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
Thank you,
Michael - <mike(@)php.net> http://dev.iworks.at/ext-http/http-functions.html.gz
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
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.
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