/Main_Page

::You must have ninja focus to complete your mission::NinjaFocus::

PHP Error Handling

Views:

(Back to the PHP page)

Contents

Custom Error Handler

I wrote this error handler to help with using library code.

PHP is just not geared for using exceptions, and they should only be used in exceptional circumstances anyway (geddit?). Exceptions are handy because php can dump them to the log, letting you see who called what and where they called it.

If you use the built in trigger_error() function, PHP will report file and line number details for your library and not the caller.

This handler allows library code to indicate where it was called from, when it finds an error in parameters or state. This requires careful use or you will end up passing round a variable to indicate call depth within your library. Try to keep it's use to the interface level only.

<?php 
/**
 * @package ninja
 * @copyright Kieran Whitbread 2006-2010
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 */

 /**
  * eAccelerator bug #162 (using php's set_error_handler with a class/object method vs a function)
  *
  * This is a simple wrapper to work around the bug.
  *
  * eAccelerator has an issue with custom error handlers implemented as methods. Functions are fine,
  * so we are using this as a work around. The bug should be fixed by the next major release, see
  * http://eaccelerator.net/ticket/162 for status and further details.
  *
  * @internal
  **/
function _ninjaErrorHandler($errno, $errstr, $errfile = '-', $errline = 0, $errcontext = array())
{
    return NinjaError::handler($errno, $errstr, $errfile, $errline, $errcontext);
}


class NinjaError
{
    protected static $oldErrorHandler = null;
    protected static function caller($depth = 0)
    {
        $backtrace = debug_backtrace();
        $callingFile = isset($backtrace[$depth]['file']) && $backtrace[$depth]['file'] ? $backtrace[$depth]['file'] : null;
        $callingLine = isset($backtrace[$depth]['line']) && $backtrace[$depth]['line'] ? $backtrace[$depth]['line'] : null;
        return array('file'=>$callingFile, 'line'=>$callingLine);
    }
    /**
     * A simple error handler that implements the documented API.
     * Please refer to the PHP documentation
     *
     * @internal
     * @return bool
     * @author Kieran Whitbread
     **/
    public static function handler($errno, $errstr, $errfile = '-', $errline = 0, $errcontext = array())
    {
        $fatal = false;
        switch($errno)
        {
            case E_USER_NOTICE:         $errtype = "CMS Notice";
                                        break;
            case E_USER_WARNING:        $errtype = "CMS Warning";
                                        break;
            case E_USER_ERROR:          $errtype = "CMS Fatal error";
                                        $fatal = true;
                                        break;
            case E_USER_DEPRECATED:     $errtype = "CMS Depreciated"; // PHP 5.3+
                                        break;
            case E_NOTICE:              $errtype = "PHP Notice";
                                        break;
            case E_WARNING:             $errtype = "PHP Warning";
                                        break;
            case E_RECOVERABLE_ERROR:   $errtype = "PHP Catchable Fatal Error";
                                        break;
            case E_STRICT:              $errtype = "PHP Strict Standards";
                                        break;
            case E_DEPRECATED:          $errtype = "PHP Depreciated"; // PHP 5.3+
                                        break;
            default:                    $errtype = "CMS Unknown Error";
                                        error_log(__METHOD__." invalid error type, $errno");
        }
        if ($errno & error_reporting())
        {
            
            error_log("$errtype: $errstr in $errfile on line $errline");
            if (ini_get('display_errors'))
            {
                echo "<br /><b>$errtype</b>: $errstr in <b>$errfile</b> on line <b>$errline</b></br />";
            }
        }
        if ($fatal) die;
        return true;
    }
    public static function register()
    {
        // eAccelerator #162
        // self::$oldErrorHandler = set_error_handler(array('NinjaError', 'handler'));
        self::$oldErrorHandler = set_error_handler('_ninjaErrorHandler');
    }
    /**
     * Implements php's trigger error but allows you to manipulate the back trace used for the error message.
     *
     * Use this with the $depth parameter from inside your library functions. It cause the error message to 
     * display the caller's file and line details, rather than those of your library code.
     *
     * @param string $message The error message
     * @param int $level The error level, defaults to E_USER_ERROR
     * @param int $depth depth of function call "responsible" for causing the error to be triggered
     * @return void
     * @author Kieran Whitbread
     **/
    public static function trigger($message, $level = E_USER_NOTICE, $depth = 0)
    {
        if (!preg_match(NINJA_PREG_UINT, $depth))
        {
            $depth = 0;
            $caller = self::caller($depth + 1);
            $callingFile = is_array($caller) && isset($caller['file']) && $caller['file'] ? $caller['file'] : '-';
            $callingLine = is_array($caller) && isset($caller['line']) && $caller['line'] ? $caller['line'] : '0';
            self::handler(E_USER_WARNING, __METHOD__." exepects parameter 3 to be long", $callingFile, $callingLine);
        }
        $caller = self::caller($depth + 1);
        $callingFile = is_array($caller) && isset($caller['file']) && $caller['file'] ? $caller['file'] : '-';
        $callingLine = is_array($caller) && isset($caller['line']) && $caller['line'] ? $caller['line'] : '0';
        self::handler($level, $message, $callingFile, $callingLine);
    }
    public static function unregister()
    {
        restore_error_handler(self::$oldErrorHandler);
        self::$oldErrorHandler = null;
    }
}

Exception Classes

  • Exception
  • OutOfBoundsException
  • InvalidArgumentException
  • InvalidLengthException
  • RangeException
  • ReflectionException
  • UnexpectedValueException

Exception Protocol

  • Exception::getMessage()
  • Exception::getFile()
  • Exception::getLine()
  • Exception::getTrace()
  • Exception::getTraceAsString()

Functions

  • set_exception_handler()
  • set_error_handler($errNo, $message, $file, $lineNo)

User Error Constants

  • E_USER_ERROR
  • E_USER_WARNING
  • E_USER_NOTICE

File Handling Error Codes

  • UPLOAD_ERR_OK (0)
  • UPLOAD_ERR_INI_SIZE (1)
  • UPLOAD_ERR_FORM_SIZE (2)
  • UPLOAD_ERR_PARTIAL (3)
  • UPLOAD_ERR_NO_FILE (4)

Useful Predefined Constants

  • __LINE__
  • __FILE__
  • __FUNCTION__
  • __METHOD__

Assertion Statements

  • assert
  • assert_options
  • assert_callback

Main Menu

Personal tools

Toolbox