PHP Custom Error Handling Continued

Right, so now we have the nice xHTML ready to slot in (you might need to have a look at previous posts in this series). Theoretically everything should work fine, but if you go back to the first part of the series you still have the problem of clearing up the useless data that PHP has outputted before the error, as it will be displayed before the doctype, invalidating the xHTML:

(useless data here)<!DOCTYPE html PUBLIC…

Here’s where the nifty bit comes in: using something called output buffering. I like to think of output buffering as pieces of paper stacked on top of each other. In this case we’ll only be using one piece of paper, but you could potentially have a lot more. By default your PHP scripts will write to a buffer (or piece of paper) and that buffer will be displayed automatically. You can interfere with this process by manually specifying your piece of paper for your script to write on, so that you can screw it up and throw it into the bin if need be. Simply call:

ob_start();

Before your output begins. Now that you have your buffer, you can throw it out as you please with:

ob_clean();

As I mentioned you can have more than one buffer (or piece of paper) so let’s have a look at this:

ob_start();

echo ‘This will display. ‘;

ob_start();

echo ‘So will this.’;

ob_start();

echo ‘No chance’;

ob_clean();

ob_end_flush();

Outputs:

This will display
So will this.

The only new thing you are seeing with is:

ob_end_flush();

All this does is to send the buffers to be displayed, and disable output buffering again. This can be combined with a custom error handler to display your errors as you intended:

function myErrorHandler ($errno, $errstr, $errfile, $errline, $errcontext) { (1)

switch ($errno) { (2)

case E_USER_ERROR:

ob_clean(); (3)

$page = &new Page(’An Error Has Occured’); (4)

$error=<<<EOD

t<h2>An Error Has Occured</h2>

<b>Error:</b> in $errfile on line $errline<br />

$errstr

EOD;

$page->addCentreContent($error); (5)

$page->addLeftContent();

$page->addRightContent();

$page->addFooter();

echo $page->returnPage();

ob_end_flush(); (6)

exit();  (7)

break;

}

}

  1. Define your custom error handler with “myErrorHandler”, this can be anything you want but you do have to follow the set parameters: “$errno”; what level of error you are handling like “E_USER_ERROR” “E_USER_NOTICE” or whatever, “$errstr”; the message you pass the function at call-time (more on this later), “$errfile”; the file where the error occurs, and “$errline”; the line number.
  2. Instead of making a code soup with if/else conditionals, it is much easier to use the switch. This takes a variable, so that you can compare it one at a time with the “cases” it could be. The “case” part of the switch basically serves as the “if ($variable == $action)” conditional. Though instead of starting with a curly bracket you use the colon, and finish with “break;”.
  3. Clean out the buffer we started before the output code.
  4. Instantiate the object made in Part 2, and build up the xHTML error page.
  5. Send the output to the browser
  6. Exit code execution so that any potential code after the error that outputs data doesn’t appear after the “</html>”

Now that the error handling function is ready, you have to make PHP recognise it as such, so it replaces its basic messages with your custom ones:

set_error_handler(‘myErrorHandler’);

Obviously this should be just underneath your error handling function. Now let’s have a look at a concept example:

echo ‘This is some table xHTML’;

if ($failedTableQuery) {

trigger_error(‘I am sorry but the data could not be retrieved from the database’,E_USER_ERROR); (1)

}

echo ‘I am making judgements on the above data’;

  1. Use “trigger_error” to make your errors

As you can see the benefits are two fold: the useless structure and the comments on the data are discarded, and you have a user friendly (well, as friendly as errors come) error. Some caveats: you will have to add further “cases” to your error handler function to deal with other types of php errors, and PHP 5 has different error handling capabilities that you should Google. Hope you found this series interesting, I welcome your comments. I think I’ll have a once over to check all the code works, but it’s nice to cross another thing off the list.