Customizing the PHP Error Handler
By Tony Marston2005-04-09
Creating the Error Handler
This is done by using the set_error_handler() function. With this you supply the name of the function you want to be called when any errors are triggered. You then create a function of this name to deal with these errors. In the following code snippets I shall use the name errorHandler.
Here I am using the switch() statement to take action depending on the value of $errno. Anything less than E_USER_ERROR will be ignored and processing will continue.
set_error_handler('errorHandler');
function errorHandler ($errno, $errstr, $errfile, $errline, $errcontext)
{
Note that by defining your own error handler the standard PHP error handler is completely bypassed and any settings for error_reporting() are completely ignored. This is why we are checking for all possible error levels, not just fatal errors.
Here I am picking up the last SQL query from a global variable. I am them checking the contents of $errstr to see if this error was triggered with the string 'SQL' so I know when to include some additional information.
switch ($errno)
{
case E_USER_WARNING:
case E_USER_NOTICE:
case E_WARNING:
case E_NOTICE:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
break;
case E_USER_ERROR:
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
Now we can start constructing an error message. I personally like to start with the current date and time.
global $query;
if (eregi('^(sql)$', $errstr)) {
$MYSQL_ERRNO = mysql_errno();
$MYSQL_ERROR = mysql_error();
$errstr = "MySQL error: $MYSQL_ERRNO : $MYSQL_ERROR";
} else {
$query = NULL;
} // if
Next we include the contents of $errno and $errstr.
$errorstring = "" .date('Y-m-d H:i:s') ."
\n";
If the error was triggered by an SQL problem I have found it of enormous benefit to include the actual query string in the error message.
$errorstring .= "Fatal Error: $errstr (# $errno).
\n";
These next lines will identify the filename and line number where the error was triggered, plus the name of the currently executing script.
if ($query) $errorstring .= "SQL query: $query
\n";
$errorstring .= "Error in line $errline of file '$errfile'.
\n";
$errorstring .= "Script: '{$_SERVER['PHP_SELF']}'.
\n";
These next lines of code show you how it is possible to extract some more information about the context of the current error. In this case if the context is an object it will extract the name of the class and the name of the parent class (if it is a derived class).
This next group of lines will send the error message to the client's browser.
if (isset($errcontext['this'])) {
if (is_object($errcontext['this'])) {
$classname = get_class($errcontext['this']);
$parentclass = get_parent_class($errcontext['this']);
$errorstring .= "Object/Class: '$classname', Parent Class: '$parentclass'.
\n";
} // if
} // if
This next line of code will send the error details to the system administrator by email.
echo "This system is temporarily unavailable
\n";
echo "The following has been reported to the administrator:
\n";
echo "\n$errorstring\n";
Here I am appending the error details to a disk file with the extension '.html' so that I can easily view its contents with my browser. This means that I do not have to wait for the email to arrive to obtain the details of the error.
error_log($errorstring, 1, $_SERVER['SERVER_ADMIN']);
The final act is to terminate the current session then cease processing altogether.
$logfile = $_SERVER['DOCUMENT_ROOT'] .'/errorlog.html';
error_log($errorstring, 3, $logfile);
session_start();
session_unset();
session_destroy();
die();
default:
break;
} // switch
} // errorHandler
Tutorial Pages:
» Customising the PHP Error Handler
» Introduction
» Creating the Error Handler
» Calling the error handler
» Summary
