#native_company# #native_desc#
#native_cta#

Error Handling in PHP 5 Page 2

By J. Leidago Noabeb
on April 16, 2012

PHP Error Handling on Production Sites

For those of you who are running production sites, switch off display_errors. Although these errors have become somewhat safer in terms of the content that it displays, they still pose a security risk to your site. To manage errors that occur during production, make use of PHP’s error-handling capabilities. To demonstrate these capabilities, we will create a custom error handler. Before we start developing our own error handler, I’d like to share the following things about PHP’s error reporting. PHP has three kinds of error levels:

  • Warnings, which indicate a problem but don’t stop a script’s execution.
  • Errors, which stop a script from continuing (including the ever-common parse error, which prevent scripts from running at all).
  • Notices, which do not stop the execution of a script and may not necessarily be a problem.

 

This will sound familiar to you, since we already looked at each type in detail. The three error types each have reporting levels as listed below:

Number

Constant

Reporting on

1

E_ERROR

Fatal runtime errors (that stop execution of the script)

2

E_WARNING

Runtime warnings (non-fatal errors)

4

E_PARSE

Parse errors

8

E_NOTICE

Notices (things that may or may not be a problem)

256

E_USER_ERROR

User-generated error messages, generated by the trigger_error() function

512

E_USER_WARNING

User-generated warnings, generated by the trigger_error() function

1024

E_USER_NOTICE

User-generated notices, generated by the trigger_error() function

2048

E_STRICT

Recommendations for compatibility and interoperability(available as from PHP6)

8191

E_ALL

All errors, warnings, and recommendations

In our custom error handler, we will try to catch the type of error that PHP is reporting and then handle it appropriately. We can either send the error to an email address, or we can log the error to a file. Our error handler will be a class, which will get its information from a config file:

Config file:

<?php
$app_name="Error Manager";
$filename = 'error_log.txt'; //filename to which the error will be logged
$email ='[email protected]';//email address to which error messages are to be sent to
$emailname = 'joe blogg'; //email recipient name
$currdate=date("l, dS of F Y @ H:i:s A");

?>

The config file contains the email address, logfile and current date information. We can easily include this information in the main class, but it is better security-wise to have it somewhere (even outside of the root) where you can make changes.

Errorhandler class:

<?php
/*
functions:
handle error - Actual error handler
vars are not echoed when the error is printed out. You can do this if you so wish
TO DO:
HTML Format error messages
*/
class errors
{

    var $msg;
    function errors()
    {
    global $filename,$email,$currdate,$app_name;
        // Populate class variables
        $this->email = $email;
        $this->logfile =$filename;
        $this->currdate=$currdate;
        $this->appname="Error Manager";
        // Take over from PHP error handling
        set_error_handler(array($this, 'handle_error'));
    }


    function handle_error($type, $string, $efile, $line, $vars)
    {

           // Decide which type of error it is, and handle appropriately
        switch ($type)
        {
            // Error type
            case E_ERROR:
            case E_USER_ERROR:
            //build the message
            $this->msg = '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line.'</b> <br>' ;
            //$this->msg .= print_r($vars);
            if(isset($this->appname)){
            $this->msg .='Error generated by <b>'.$this->appname.'</b> on <b>'.$this->currdate.'</b><br>';
            }else{
             $this->msg .='Error generated on <b>'.$this->currdate.'</b><br>';
            }
            echo '<br>';
            /*//log the error to file
            error_log($this->msg,3,$this->logfile);
            //sent message to web administrator
            error_log($this->msg,1,$this->email); */
            //print out message
           echo '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line. '</b><br>' ;
           echo 'Error generated on <b>'.$this->currdate.'</b><br>';
           echo '<br>';
            break;


             case E_WARNING:
             case E_USER_WARNING:
             //build the message
            $this->msg = '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line.'</b> <br>' ;
           // $this->msg .= print_r($vars);
             if(isset($this->appname)){
            $this->msg .='Error generated by <b>'.$this->appname.'</b> on <b>'.$this->currdate.'</b><br>';
            }else{
             $this->msg .='Error generated on <b>'.$this->currdate.'</b><br>';
            }
            echo '<br>';
            /*//log the error to file
            error_log($this->msg,3,$this->logfile);
            //sent message to web administrator
            error_log($this->msg,1,$this->email); */
            //print out message
           echo '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line. '</b><br>' ;
           echo 'Error generated on <b>'.$this->currdate.'</b><br>';
          echo '<br>';
             break;

             case E_PARSE:
            //build the message
            $this->msg = '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line.'</b> <br>' ;
          //  $this->msg .= print_r($vars);
             if(isset($this->appname)){
            $this->msg .='Error generated by <b>'.$this->appname.'</b> on <b>'.$this->currdate.'</b><br>';
            }else{
             $this->msg .='Error generated on <b>'.$this->currdate.'</b><br>';
            }
            echo '<br>';
            /*//log the error to file
            error_log($this->msg,3,$this->logfile);
            //sent message to web administrator
            error_log($this->msg,1,$this->email); */
            //print out message
           echo '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line. '</b><br>' ;
           echo 'Error generated on <b>'.$this->currdate.'</b><br>';
           echo '<br>';
            break;

            case E_NOTICE:
            case E_USER_NOTICE:
            //build the message
            $this->msg = '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line.'</b> <br>' ;
           // $this->msg .= print_r($vars);
             if(isset($this->appname)){
            $this->msg .='Error generated by <b>'.$this->appname.'</b> on <b>'.$this->currdate.'</b><br>';
            }else{
             $this->msg .='Error generated on <b>'.$this->currdate.'</b><br>';
            }
            echo '<br>';
            /*//log the error to file
            error_log($this->msg,3,$this->logfile);
            //sent message to web administrator
            error_log($this->msg,1,$this->email); */
            //print out message
           echo '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line. '</b><br>' ;
           echo 'Error generated on <b>'.$this->currdate.'</b><br>';
           echo '<br>';
             break;
        }

    }

    }



?>

The errorhandler class uses a function called handle_error() to list all the available error reporting levels and constructs a message using the reported error:

function handle_error($type, $string, $efile, $line, $vars)
    { 
 
           // Decide which type of error it is, and handle appropriately
        switch ($type)
        {
            // Error type
            case E_ERROR:
            case E_USER_ERROR:
            //build the message
            $this->msg = '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line.'</b> <br>' ;
            //$this->msg .= print_r($vars);
            if(isset($this->appname)){
            $this->msg .='Error generated by <b>'.$this->appname.'</b> on <b>'.$this->currdate.'</b><br>';
            }else{
             $this->msg .='Error generated on <b>'.$this->currdate.'</b><br>';
            }
            echo '<br>';

Then it writes the error message to a file:

            /*//log the error to file
            error_log($this->msg,3,$this->logfile);

And then sends the error to the email address that was defined in the config file:

            //sent message to web administrator
            error_log($this->msg,1,$this->email); */
            //print out message
           echo '<b>Error:</b> <br> Error message: <b>'.$string.'</b> in <b>'.$efile.'</b> on line <b>'. $line. '</b><br>' ;
           echo 'Error generated on <b>'.$this->currdate.'</b><br>';
           echo '<br>';
            break;

To test the errorhandler class, you simply do the following:

<?php
include "errorhandler.class.php";
include "config/errorhandler.conf.php";
//instantiate the class
 $errors = new errors();
//trigger some  errors
$row = mysql_fetch_array($result);
100/0;
?>

I’ve included the source code for download.

Conclusion

Handling errors this way keeps your site secure and enables you to deal with any errors in the background. The error handler can, of course, be expanded to include any new error reporting levels that might be introduced in the newer versions of PHP.