4 Fantastic PHP Output Buffering Tricks for Web Developers
Tuesday, April 21st, 2009 Tags: output-buffering
If you've read my Dev Tips article Output Buffering for Web Developers, a Beginner's Guide you know that PHP output buffering is useful and awesome at the same time.
To recap the article, output buffering puts your PHP script's output in a buffer instead of sending it directly to the browser in pieces, allowing you to manipulate your webpage as a whole before the user sees it. That awesomeness is what we'll take advantage of now.
To prevent reinventing the wheel, we'll reuse the code we wrote in Output Buffering for Web Developers, a Beginner's Guide:
<?php
// start output buffering at the top of our script with this simple command
// we've added "ob_postprocess" (our custom post processing function) as a parameter of ob_start
ob_start('ob_postprocess');
?>
<html>
<body>
<p>Hello world!</p>
</body>
</html>
<?php
// end output buffering and send our HTML to the browser as a whole
ob_end_flush();
// ob_postprocess is our custom post processing function
function ob_postprocess($buffer)
{
// do a fun quick change to our HTML before it is sent to the browser return $buffer;
}
?>
Specifically, we’ll use the ob_postprocess($buffer) function for each tip.
1. Optimize HTML by removing repeating spaces
Repeated spaces don't render in a browser, but your end-user still has to download all the extra space characters as bytes. Let's turn repeating spaces into only one space.
function ob_postprocess($buffer)
{
$buffer = trim(preg_replace('/\s+/', ' ', $buffer));
return $buffer;
}
2. Compress HTML with gzip
Compressing your output with gzip is a highly recommended practice by anybody who deals with website performance, including Yahoo!.
function ob_postprocess($buffer)
{
// check if the browser accepts gzip encoding. Most do, but just in case
if(strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
{
$buffer = gzencode($buffer);
header('Content-Encoding: gzip');
}
return $buffer;
}
3. Add acronyms to HTML
Adding the <acronym> tag all over your page can be a pain in the butt. Luckily, we can use PHP output buffering to do it for us.
function ob_postprocess($buffer)
{
$acronyms['html'] = 'hypertext markup language';
$acronyms['css'] = 'cascading style sheets';
foreach($acronyms as $acronym => $meaning)
{
$buffer = preg_replace('/(\b' . $acronym . '\b)(?=[^>]*<)/i', '<acronym title="' . $meaning . '">\\1</acronym>', $buffer);
}
return $buffer;
}
4. Encode characters as HTML entities
Are you using styled quotes and ellipses? Are you using & instead of a raw ampersand? Use PHP output buffering to do the heavy lifting for you.
function ob_postprocess($buffer)
{
// add styled double quotes
$buffer = preg_replace('/"(?=[^>]*<)([^"]*)"(?=[^>]*<)/u', '“\\1”', $buffer);
// add styled apostrophes
$buffer = preg_replace("/'(?=[^>]*<)/i", "’", $buffer);
// add ellipses
$buffer = str_replace('...', '…', $buffer);
// encode ampersands
$buffer = str_replace('&', ' & ', $buffer);
return $buffer;
}
That's all I'm going to give you for now. I can't give you all of my secrets in one post!
Enjoy fooling around with the buffer in a socially acceptable way, and let us know if you find anything too cool to keep to yourself.
Tags: output-bufferingIf you enjoyed this article, you might consider subscribing to our rss feed to stay updated with all the latest tips and articles!
Article Sponsored by:
There is much to learn about the World's most popular publishing platform. From your first steps of learning about WordPress all the way through maintaining a site throughout the years, this book is packed with truly practical information.









Thanks for publishing this article! Tell me your thoughts! (or else)
Thanks for continuing to do this series Brian! This really has been my favorite server side topic we have covered, I hope you might have more planned in the future
One thing I would like to ask or perhaps see in the future, is how big (if at all) are the performance benefits numbers wise?
Anyway, thanks again Brian!
Hi Brian,
Nice illustration of the funky things that can be done with output buffering, few comments/critiques:
#1) Seems like the overhead of running preg_replace over your entire output would eat the say, 500 byte (if that) saving?
#2) Wouldn’t you let the webserver do this?
#3) Nice idea
#4) Can see the benefit, but would have thought this would be dealt with in the original markup/db output.
Cheers,
- Paul
Paul:
#1) It’s a really simple preg_replace, so I’m not sure. It comes in even more handy when the file is cached. Haven’t done tests, but I use it anyway. Plus it makes it more difficult for people to copy my work.
#2) True, this might be accomplished through .htaccess, or through php.ini, but this is one way of doing it. You can also control the level of compression here. See PHP’s documentation on gzencode for more info.
#3) Thanks
#4) I don’t like worrying about whether or not I’m encoding my characters because I like to make PHP work for me, not me for it. So I make PHP do the encoding for me (including styled quotes instead of straight quotes)
Definitely with you on making the machine do the grunt work – just saying I’d probably do it elsewhere in the app
Other ideas:
Replace characters with images? Stylised quotes with graphical quotes, smileys, etc.
Autolink keywords, your name back to your blog perhaps.
Add footers.
Performance considerations aside, it’s really only limited by your imagination
Thanks again for the article.
paul: “Performance considerations aside, it’s really only limited by your imagination” is exactly right
Thanks for the suggestions. I’ll keep them in mind on possible future posts
sweet DevTip dued! or should I say Bc!
Thanks CD!
Hi Brian, great article!! The Yahoo! link points to “http://developer.yahoo.com/performance/rules.html#gzi” instead of “http://developer.yahoo.com/performance/rules.html#gzip”.
Hey Bleyder,
Looks like Brian fixed it already, thanks for pointing that out for us
Can someone explain this one to me?
$buffer = str_replace(‘ & ‘, ‘ & ‘, $buffer);
Seems like to me that you’re not making in change with that code. Shouldn’t it be something more like $buffer = str_replace(‘ & ‘, ‘ & ‘, $buffer);
Sorry looks like that got in encoded..
$buffer = str_replace(‘ & ‘, ‘ & ‘, $buffer);
vs
$buffer = str_replace(‘ & ‘, ‘ & ‘, $buffer);
The second one is the correct one, I think it was just an encoding problem when submitting the article.
Thanks for mentioning that. As Vasili suggested, it was an encoding issue when we published the post. It should be fixed now
Some of this is very handy, allthough it could cause real problems if you do it like that. Espechially Nr. 4 & Javascript etc.
In a web application you usually have views or templates. You should concentrate to have your templates clean. I would use such a function only for User Input.
However its a nice idea
Isn’t it much simpler to turn on zlib.output_compression in php.ini instead of creating a useless ob_postprocess() function just to compress the output?
You make the mistake of assuming the user has access and/or permissions to alter their php.ini configuration on the server.
Love the acronyms trick. Useful in so many ways
Hi Brian
I am a newbie to php, I have a code
<?php
ob_start();
while($i
what I am trying to do is to output a number after one second, but my browser output the whole content at once,
is it possible with ob_start() ??
Thanks
Hi Brian
I am a newbie to php, I have a code
<?php
ob_start();
while($i
what I am trying to do is to output a number after one second, but my browser output the whole content at once,
is it possible with ob_start() ??
Thanks
Hi,
Great tips, do anyone know how to best implement this in wordpress or is it already done?
Brian
I find unencoded ampersands are usually the first thing to bork an otherwise valid page.
But we really only want to filter on ampersands that aren’t already part of an entity (typically in a URL).
$buffer = preg_replace('/&(?!#?\w+;)/', '&', $buffer);
Now I wonder how that will look?
hi. how would i do the reverse of this. i.e. convert only encoded ampersands that are in hrefs to a straight &? backwards i know but i need to do this and my brain hurts. thanks!
Hi Mark
That’s an interesting question. What’s encoding them before they’re sent to the output buffer? How about a usage example?
@Patrik:
Place the
ob_start()right at the top of your Wordpress theme’sfunctions.phpfile. This file is loaded before any ouput is generated (other than headers, natch).// file = theme\functions.php
// Start output buffering
ob_start('ob_postprocess');
function ob_postprocess($buffer)
// do your thang here
// finally send it to the browser
return $buffer;
}
// remainder of functions.php...
The
ob_end_flush()call could be added at the end of your theme’sfooter.php, but is not strictly required since the callback function will be called regardless. My experience anyways, since PHP5+.So what about if you want all of that in one script. How do you combine everything?
One of my late favorites is ob_implicit_flush() which works pretty much exactly opposite to your suggestions. Flushing the output buffer constantly is very nice especially when running batches that take long to finish, since it’s possible to see the results on the fly.