How I PHP: The Output Handler
There are some techniques that I use in almost all of my projects, but I hardly see in other projects. To my opinion others are missing out, so I’ll discuss a few of them, to start off with the use of an output handler. The output buffer caches the output data before it is send to the browser. Before the data is actually send, you have the possibility to use modify it.
Let me give a practical example of how I use the output buffer when developing websites. A website usually has a part which is common across all pages, containing the HTML header, the menu and those kinds of things. This is often solved in one of four ways:
- have the content in each script
- the use of include(’header.php’)/include(’footer.php’) or print_header()/print_footer()
- using a templating system (like Smarty)
- using a single entry point
All of these methods work, however there is a better way to solve this. You guessed it, by using an output handler.
Have a look at the following random website template. Each page would be mostly the same with only the content in the middle changing.
We’ll start with making a template file, with all of the content that is the same for each page. In the template we’ll put a marker in the form of an HTML comment tag.
[SOURCE::output_handler/obdemo/template.html::xml]
The index page ‘index.php’ contains the content of the page and includes ‘init.php’. The other scripts look similar.
[SOURCE::output_handler/obdemo/index.php::php]
Now for the magic. In ‘init.php’ we will create a create a class which adds an output handler callback function.
<?php class OutputHandler { protected $template; protected $footer; function __construct($template) { $this->template = $template; ob_start(array($this, 'callback')); } function callback($buffer, $flags) { if (!isset($this->footer)) { list($header, $this->footer) = preg_split('/<!--\s*MARK:\s*CONTENT\s*-->/i', $this->template, 2); $buffer = $header . $buffer; } if ($flags & PHP_OUTPUT_HANDLER_END) { $buffer .= $this->footer; } return $buffer; } } new OutputHandler(file_get_contents('template.html')); # Other initialisation here, like connecting to a db ?>
The callback function will split the template in a header and a footer and paste the header in front of the content. We can check if there will be more content using the second parameter, $flag. If the flush occured because it is the end of the request, we paste the footer after the content.
I love this solution much more than the others, because we still have one script per page which works so well for websites, but the script files stay nice and clean.
In this example the template is very static, but with a bit of emagination you can think of way to make it more dynamic. In lots of cases I define the structure of the website in XML and than create the template with XSLT. Another way is to use a preg_replace to add some dynamic content. At least, I hope I’ve given you some ideas.
11 Nov 2007 Arnold Daniels





“In lost of cases”
typo
Nice simple feature, thanks for posting it.
Ehh, just in case some beginner or even someone who over looked your article, you might want to adjust the difference of ‘init.php’ and ‘init.inc’ in your article.
Thanks Joe,
It should be ‘init.php’. I prefer using .inc, because that won’t be executed on my server. However in examples I use .php, because on some servers the contents of .inc files gets displayed.
hey, thanks for sharing this, I’ve already used something like that a few times. But I keep wondering – what about the performance?
This seems to work pretty well and clean, however I am a little confused on how you would expand this.
For instance:
In your index file you might want to independently control part of the header, the menu, and of course the content so your template file would need three separate calls and then your callback would need to be able to sort out those calls in your index file. Does that make sense?
How would handle this functionality?
Thanks, David
I’ll get back on that in a new post, David.
Looking forward to it, always looking for ways to clean up and better process my code and markup!
-d
Looks great. Now I have to check it
This is interesting and useful because I hadn’t even realised the output buffering functions existed! However I don’t really see that it’s any better than having something like this, which is simpler…
display_page.php (incorporating the template html):
etc.
etc.
then index.php:
etc. etc.
HTML;
< ?
display_page($content);
?>
This way it’s also very easy to add extra parameters to the display_page function, for instance telling it how menus should appear. No messing round with regular expressions. I think I’ll be sticking with this way for the time being!
Stuart,
I must say that I don’t think your example is very clear. What is $content? What does display_page.php do?
Do you build up the output as string instead of echo’ing it and than put it into a function? If so, I really don’t like that approach, because you loose the whole templating feature of PHP.
You can use PHP the template when use the output buffer and than simply include the template PHP file, because echo’ing stuff won’t work and even ob_start, ob_get_contents won’t work correctly. That’s why I use regulair expressions. And I can just say: Don’t fear regexs, but learn to love them.
Have you benchmarked the performance of this approach against the other `usual` ways to handle this type of functionality ?
I am sorry for the repeated comment, but the first one seems to be `butchered` because of the quotes I used in it.
Another thing that I forgot: very often you need to inject values or do other changes to the header and footer. I do not see how we can do this with the example you presented above. Can you show another example highlighting how to modify the header and the footer ?
Sorry – the example I tried to give wasn’t clear because most of it got stripped out! I’ve put up what it should have said (as far as I can remember!) at http://www.google.co.uk/notebook/public/09355657237885062984/BDSCAQgoQ2vDz5PMi?hl=en
As I said before, the function display_page can then be made more complicated by adding more parameters, e.g. telling it how to display the menu.
My point is that this is simpler — easier to write and debug — than using the in-built template functions combined with regex, and so I don’t see the advantage of using the latter approach. I don’t fear regular expressions for genuine string manipulation but they seem a messy solution for this type of thing…?