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.
A random site

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.

See it working
Download the source code