PHP

Custom Error Handlers

A custom error handler is used in the winestore in preference to the built-in PHP error handler. Example 10-8 shows this handler incorporated in the include file error.inc.

Example 10-8. The error.inc custom error handler
<?
   // Trigger an error condition
   function showerror(  )
   {
      if (mysql_errno() || mysql_error(  ))
         trigger_error("MySQL error: " .
                        mysql_errno(  ) .
                        " : " . mysql_error(  ),
                        E_USER_ERROR);
      else
         trigger_error("Could not connect to DBMS",
                        E_USER_ERROR);
   }
   // Abort on error. Deletes session variables to leave
   // us in a clean state
   function errorHandler($errno, $errstr,
                         $errfile, $errline)
   {
      switch ($errno)
      {
         case E_USER_NOTICE:
         case E_USER_WARNING:
         case E_WARNING:
         case E_NOTICE:
         case E_CORE_WARNING:
         case E_CORE_NOTICE:
         case E_COMPILE_WARNING:
            break;
         case E_USER_ERROR:
         case E_ERROR:
         case E_PARSE:
         case E_CORE_ERROR:
         case E_COMPILE_ERROR:
            session_start(  );
            if (session_is_registered("message"))
               session_unregister("message");
            if (session_is_registered("order_no"))
               session_unregister("order_no");
            $errorString =
  "Winestore system error: $errstr (# $errno).<br>\n" .
  "Please report the following to the administrator:<br>\n" . "Error in line $errline of file $errfile.<br>\n";
            // Send the error to the administrator by email
            error_log($errorString, 1, "Alexa");
?>
<h2>Alexa and Dave's Online wines is temporarily unavailable</h2>
The following has been reported to the administrator:
<br><b><font color="red"><?=$errorString;?></b></font>
<?php
            // Stop the system
            die(  );
         default:
            break;
      }
   }
?>

At the beginning of each script in the winestore application, the handler is registered:

set_error_handler("errorHandler");

After this registration, any error, warning, or notice encountered in the script will cause the function errorHandler( ) to be called.

The function set_error_handler( ) has the following prototype:

string set_error_handler(string error_handler)

On success, the function returns the previously defined error handler function name as a string. The parameter error_handler is the name of the user-defined handler function, in our example errorHandler. The returned value can be used later to restore the previous error handler with set_error_handler( ).

PHP requires that the user-defined errorHandler( ) function have at least two parameters: an error number and an error string. Three additional optional parameters can be included in a custom error handler: the script file that caused the error, the line number with the error, and additional variable context information. Our handler supports the first two of the three optional parameters.

Eight different errors, warnings, and notices can be generated by PHP during script processing or during the precompilation process, generated by the PHP script engine itself, or triggered manually by the developer. Our errorHandler( ) function ignores all notices and warnings by returning if the error number errno parameter falls into the WARNING or NOTICE classes. However, for all errors in the ERROR class and for PARSE errors, our custom error handler carries out several actions:

  1. It logs out the user and deletes any registered session messages.

  2. It creates a string that incorporates details of the error.

  3. It emails the error message to the system administrator-in this case to the email account Alexa-using the PHP library error_log( ) function.

  4. It outputs the error message to the browser.

The advantage of a custom error handler is that additional features, such as deleting session variables, closing database connections, and sending email messages, can be incorporated in the error process.

The error_log( ) function has the following prototype:

int error_log (string message, int message_type [, string destination [, string extra_headers]])

The string message is the error message to be logged. The message_type can be 0, 1, or 3. A setting of 0 sends the message to the PHP system error logger, which is configured using the error_log directive in the php.ini file. A setting of 1 sends an email to the destination email address using the mail( ) function with any additional email extra_headers that are provided; the mail( ) function and the use of extra headers is discussed in Chapter 12. A setting of 3 appends the message to the file destination. A setting of 2 isn't available in PHP4.

The showerror( ) function is also part of error.inc. This function is called whenever a MySQL function fails throughout the winestore scripts. The function tests if mysql_error( ) or mysql_errno( ) return nonzero values and, if so, it triggers a user-generated error using the trigger_error( ) PHP library function:

void trigger_error (string error_message [, int error_type])

The trigger_error( ) function has two parameters: an error_message-which is created using the return values of the MySQL error functions-and an optional error_type that's set to E_USER_ERROR. If MySQL hasn't reported an error, the mysql_connect( ) or mysql_pconnect( ) functions have failed, and a message indicating this is manually created. The result of calling trigger_error( ) is that the PHP script engine calls our custom registered handler, errorHandler( ).