预定义异常
在线手册:中文 英文
PHP手册

ErrorException

(PHP 5 >= 5.1.0)

简介

错误异常。

类摘要

ErrorException extends Exception {
/* 属性 */
protected int $severity ;
/* 方法 */
public __construct ([ string $message = "" [, int $code = 0 [, int $severity = 1 [, string $filename = __FILE__ [, int $lineno = __LINE__ [, Exception $previous = NULL ]]]]]] )
final public int getSeverity ( void )
/* 继承的方法 */
final public string Exception::getMessage ( void )
final public Exception Exception::getPrevious ( void )
final public int Exception::getCode ( void )
final public string Exception::getFile ( void )
final public int Exception::getLine ( void )
final public array Exception::getTrace ( void )
final public string Exception::getTraceAsString ( void )
public string Exception::__toString ( void )
final private void Exception::__clone ( void )
}

属性

severity

异常级别

范例

Example #1 使用set_error_handler()函数将错误信息托管至ErrorException

<?php
function exception_error_handler($errno$errstr$errfile$errline ) {
    throw new 
ErrorException($errstr0$errno$errfile$errline);
}
set_error_handler("exception_error_handler");

/* Trigger exception */
strpos();
?>

以上例程的输出类似于:

Fatal error: Uncaught exception 'ErrorException' with message 'Wrong parameter count for strpos()' in /home/bjori/tmp/ex.php:8
Stack trace:
#0 [internal function]: exception_error_handler(2, 'Wrong parameter...', '/home/bjori/php...', 8, Array)
#1 /home/bjori/php/cleandocs/test.php(8): strpos()
#2 {main}
  thrown in /home/bjori/tmp/ex.php on line 8

Table of Contents


预定义异常
在线手册:中文 英文
PHP手册
PHP手册 - N: ErrorException

用户评论:

Lucas Biernot (14-Oct-2011 08:37)

It's a bad practice to ignore notices. Well written program doesn't generate notices, so imho notice is simply an error and it should raise an exception and eventually terminate the script. You can catch exception wherever you want to and perform proper action.

vog at notjusthosting dot com (02-May-2011 01:14)

There is a contradiction between the class synopsis and the example code.

The class synopsis states that the error code ($code) is the 2nd argument, while the example code provides the error code ($errno) as the 3rd argument.

Assuming that the class synopsis is correct, the example code should be corrected to:

<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new
ErrorException($errstr, $errno, 0, $errfile, $errline);
}
set_error_handler("exception_error_handler");

/* Trigger exception */
strpos();
?>

triplepoint at gmail dot com (02-Jan-2010 04:16)

As noted below, it's important to realize that unless caught, any Exception thrown will halt the script.  So converting EVERY notice, warning, or error to an ErrorException will halt your script when something harmlesss like E_USER_NOTICE is triggered.

It seems to me the best use of the ErrorException class is something like this:

<?php
function custom_error_handler($number, $string, $file, $line, $context)
{
   
// Determine if this error is one of the enabled ones in php config (php.ini, .htaccess, etc)
   
$error_is_enabled = (bool)($number & ini_get('error_reporting') );
   
   
// -- FATAL ERROR
    // throw an Error Exception, to be handled by whatever Exception handling logic is available in this context
   
if( in_array($number, array(E_USER_ERROR, E_RECOVERABLE_ERROR)) && $error_is_enabled ) {
        throw new
ErrorException($errstr, 0, $errno, $errfile, $errline);
    }
   
   
// -- NON-FATAL ERROR/WARNING/NOTICE
    // Log the error if it's enabled, otherwise just ignore it
   
else if( $error_is_enabled ) {
       
error_log( $string, 0 );
        return
false; // Make sure this ends up in $php_errormsg, if appropriate
   
}
}
?>

Setting this function as the error handler will result in ErrorExceptions only being thrown for E_USER_ERROR and E_RECOVERABLE_ERROR, while other enabled error types will simply get error_log()'ed.

It's worth noting again that no matter what you do, "E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT" will never reach your custom error handler, and therefore will not be converted into ErrorExceptions.  Plan accordingly.

randallgirard at hotmail dot com (11-Dec-2009 11:32)

E_USER_WARNING, E_USER_NOTICE, and any other non-terminating error codes, are useless and act like E_USER_ERROR (which terminate) when you combine a custom ERROR_HANDLER with ErrorException and do not CATCH the error. There is NO way to return execution to the parent scope in the EXCEPTION_HANDLER.

<?php
   
    error_reporting
(E_ALL);
   
define('DEBUG', true);
   
define('LINEBREAK', "\r\n");
   
   
error::initiate('./error_backtrace.log');
   
    try
       
trigger_error("First error", E_USER_NOTICE);
    catch (
ErrorException $e )
        print(
"Caught the error: ".$e->getMessage."<br />\r\n" );
   
   
trigger_error("This event WILL fire", E_USER_NOTICE);
   
   
trigger_error("This event will NOT fire", E_USER_NOTICE);
   
    abstract class
error {
       
        public static
$LIST = array();
       
        private function
__construct() {}
       
        public static function
initiate( $log = false ) {
           
set_error_handler( 'error::err_handler' );
           
set_exception_handler( 'error::exc_handler' );
            if (
$log !== false ) {
                if ( !
ini_get('log_errors') )
                   
ini_set('log_errors', true);
                if ( !
ini_get('error_log') )
                   
ini_set('error_log', $log);
            }
        }
       
        public static function
err_handler($errno, $errstr, $errfile, $errline, $errcontext) {
           
$l = error_reporting();
            if (
$l & $errno ) {
               
               
$exit = false;
                switch (
$errno ) {
                    case
E_USER_ERROR:
                       
$type = 'Fatal Error';
                       
$exit = true;
                    break;
                    case
E_USER_WARNING:
                    case
E_WARNING:
                       
$type = 'Warning';
                    break;
                    case
E_USER_NOTICE:
                    case
E_NOTICE:
                    case @
E_STRICT:
                       
$type = 'Notice';
                    break;
                    case @
E_RECOVERABLE_ERROR:
                       
$type = 'Catchable';
                    break;
                    default:
                       
$type = 'Unknown Error';
                       
$exit = true;
                    break;
                }
               
               
$exception = new \ErrorException($type.': '.$errstr, 0, $errno, $errfile, $errline);
               
                if (
$exit ) {
                   
exc_handler($exception);
                    exit();
                }
                else
                    throw
$exception;
            }
            return
false;
        }
       
        function
exc_handler($exception) {
           
$log = $exception->getMessage() . "\n" . $exception->getTraceAsString() . LINEBREAK;
            if (
ini_get('log_errors') )
               
error_log($log, 0);
            print(
"Unhandled Exception" . (DEBUG ? " - $log" : ''));
        }
       
    }
?>

gozlan at nett dot co dot il (01-Jun-2009 11:00)

If you want to control when the exception will be display or when not, you can change the value and enter if condition statement:

<?php
function lockdown($exception)
{
    echo
" <strong>lockdown:</strong> " , $exception->getMessage();
}

$lockdown = true; //you can change to false if you want to disable the lockdown.
if ($lockdown){
set_exception_handler('lockdown');
throw new
Exception('the website is under construction, we will be back soon');
}
?>

the output will be:
lockdown: the website is under construcytion, we will be back soon

and nothing else will be shown in the entire website, just the lockdown comment.

e dot sand at elisand dot com (26-Feb-2009 07:11)

If you're looking for a quick one-line way to change all errors in to Exceptions, you can do it this way:

set_error_handler(create_function('$a, $b, $c, $d', 'throw new ErrorException($b, 0, $a, $c, $d);'), E_ALL);

using create_function() saves you a few lines of code by embedding it all in to a single line, plus saves your namespace from a function name that should only ever be called in the event of an error (this saves from direct invocation).

luke at cywh dot com (23-Feb-2009 07:56)

To add to the comments made by chris AT cmbuckley DOT co DOT uk about the ErrorException problem with args:

I noticed that the problem is in the ErrorException class itself, not the Exception class. When using just the exception class, it's no longer an issue. Besides the args problem, the only difference between Exception and ErrorException in the stack trace is that the args are left out of the error handler exception function. I'm not sure if this was on purpose or not, but it shouldn't hurt to show this information anyway.

So instead of using this broken extended class, you can ignore it and make your own extended class and avoid the problem all together:

<?php

header
('Content-Type: text/plain');

class
ErrorHandler extends Exception {
    protected
$severity;
   
    public function
__construct($message, $code, $severity, $filename, $lineno) {
       
$this->message = $message;
       
$this->code = $code;
       
$this->severity = $severity;
       
$this->file = $filename;
       
$this->line = $lineno;
    }
   
    public function
getSeverity() {
        return
$this->severity;
    }
}

function
exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new
ErrorHandler($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler("exception_error_handler", E_ALL);

function
A() {
   
$foo->bar; // Purposely cause error
}

function
B($c) {
   
A();
}

try {
   
B('foobar');
} catch (
Exception $e) {
   
var_dump($e->getTrace());
}

?>

The only thing I wish I could do was remove the entry for the error handler function because it's quite irrelevant. Maybe that's what they were trying to do with the ErrorException class? Either way, you can't change it because the trace functions are final, and the variable is private.

chris AT cmbuckley DOT co DOT uk (13-Nov-2008 12:24)

The backtrace of ErrorException is broken in PHP 5.2 (listed at http://bugs.php.net/bug.php?id=46449 and explained at http://bugs.php.net/bug.php?id=45895#c140511).

A simple fix for your exception handler:

<?php
$backtrace
= $exception->getTrace();

if (
$exception instanceof ErrorException) {
    for (
$i = count($backtrace) - 1; $i > 0; --$i) {
       
$backtrace[$i]['args'] = $backtrace[$i - 1]['args'];
    }
}
?>

makariverslund at gmail dot com (10-Sep-2008 02:08)

Building upon the notes present, here is a set of functions that transforms the error into an exception and reports the error to screen / log depending upon the PHP ini settings.

//Begin helper function definition
function ReportError ($msg)
{
    // be sure that the supplied parameter is a string and not empty
    if (empty ($msg) || !is_string ($msg))
    {
        throw new ErrorException ('Invalid parameter supplied to ReportError', 0, E_ERROR);
    }
   
    // retrieve error settings
    $display    = strtolower (ini_get ('display_errors'));
    $log        = strtolower (ini_get ('log_errors'));
   
    // check if we're displaying errors
    if ($display === 'on' || $display === '1' || $display === 1 || $display === 'true' || $display === true)
    {
        echo $msg;
    }
   
    // check if we're logging errors
    if ($log === 'on' || $log === '1' || $log === 1 || $log === 'true' || $log === true)
    {
        $result = error_log ($msg);
       
        // check for error while logging
        if (!$result)
        {
            throw new ErrorException ('Attempt to write message to error log failed in ReportError', 0, E_ERROR);
        }
    }
}

//Begin main function definition
function ErrorsAsExceptions ($level, $msg, $fileName, $lineNumber)
{
    // do nothing if error reporting is turned off
    if (error_reporting () === 0)
    {
        return;
    }

    // be sure received error is supposed to be reported
    if (error_reporting () & $level)
    {   
        try
        {
            // report error to appropriate channels
            ReportError ($reportMsg);
        }
        catch (ErrorException $e)
        {
            // ignore errors while reporting
        }
       
        // go ahead and throw the exception
        throw new ErrorException ($msg, 0, $level, $fileName, $lineNumber);
    }
}

troelskn at gmail dot com (29-Jul-2008 12:08)

The following snippet installs an error-handler that turns errors into exceptions. It respects error-reporting level, so that you can still use error-suppression:

<?php
function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (
error_reporting() == 0) {
    return;
  }
  if (
error_reporting() & $severity) {
    throw new
ErrorException($message, 0, $severity, $filename, $lineno);
  }
}
set_error_handler('exceptions_error_handler');
?>