July 31st, 2005
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;
}
}
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’;
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.