# set_error_handler

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

set_error_handler — 设置用户自定义的错误处理函数

### 说明

set_error_handler ( callable `$error_handler` [, int `$error_types` = E_ALL | E_STRICT ] ) : mixed

设置用户的函数 (`error_handler`) 来处理脚本中出现的错误。

本函数可以用你自己定义的方式来处理运行中的错误， 例如，在应用程序中严重错误发生时，或者在特定条件下触发了一个错误(使用 trigger_error())，你需要对数据/文件做清理回收。

重要的是要记住 `error_types` 里指定的错误类型都会绕过 PHP 标准错误处理程序， 除非回调函数返回了 `FALSE`。 error_reporting() 设置将不会起到作用而你的错误处理函数继续会被调用 —— 不过你仍然可以获取 error_reporting 的当前值，并做适当处理。 需要特别注意的是带 @ error-control operator 前缀的语句发生错误时，这个值会是 0。

同时注意，在需要时你有责任使用 die()。 如果错误处理程序返回了，脚本将会继续执行发生错误的后一行。

以下级别的错误不能由用户定义的函数来处理： `E_ERROR`、 `E_PARSE`、 `E_CORE_ERROR`、 `E_CORE_WARNING`、 `E_COMPILE_ERROR`、 `E_COMPILE_WARNING`，和在 调用 set_error_handler() 函数所在文件中产生的大多数 `E_STRICT`。

如果错误发生在脚本执行之前（比如文件上传时），将不会 调用自定义的错误处理程序因为它尚未在那时注册。

### 参数

`error_handler`

  以下格式的回调（callback）： 可以传入 `NULL` 重置处理程序到默认状态。 除了可以传入函数名，还可以传入引用对象和对象方法名的数组。

  handler ( int `$errno` , string `$errstr` [, string `$errfile` [, int `$errline` [, array `$errcontext` ]]] ) : bool
  `errno`
    第一个参数 `errno`，包含了错误的级别，是一个 integer。
  `errstr`
    第二个参数 `errstr`，包含了错误的信息，是一个 string。
  `errfile`
    第三个参数是可选的，`errfile`， 包含了发生错误的文件名，是一个 string。
  `errline`
    第四个参数是一个可选项， `errline`， 包含了错误发生的行号，是一个 integer。
  `errcontext`
    第五个可选参数， `errcontext`， 是一个指向错误发生时活动符号表的 array。 也就是说，`errcontext` 会包含错误触发处作用域内所有变量的数组。 用户的错误处理程序不应该修改错误上下文（context）。
    Warning

    PHP 7.2.0 后此参数被弃用了。 极其不建议依赖它。

  如果函数返回 `FALSE`，标准错误处理处理程序将会继续调用。

`error_types`

  就像error_reporting 的 ini 设置能够控制错误的显示一样， 此参数能够用于屏蔽 `error_handler` 的触发。 如果没有该掩码， 无论 error_reporting 是如何设置的， `error_handler` 都会在每个错误发生时被调用。

### 返回值

如果之前有定义过错误处理程序，则返回该程序名称的 string；如果是内置的错误处理程序，则返回 `NULL`。 如果你指定了一个无效的回调函数，同样会返回 `NULL`。 如果之前的错误处理程序是一个类的方法，此函数会返回一个带类和方法名的索引数组(indexed array)。

### 更新日志

版本 | 说明
--- | ---
7.2.0 | `errcontext` 被废弃。 使用此参数时会导致 `E_DEPRECATED` 提醒。
5.5.0 | `error_handler` 可接收 `NULL`。
5.2.0 | 错误处理器必须返回 `FALSE` 来显示 $php_errormsg。

### 范例

Example #1 用 set_error_handler() 和 trigger_error() 进行错误处理

以下示例展示了通过触发错误并以用户自定义的程序来进行内部异常的处理。

    <?php
    // error handler function
    function myErrorHandler($errno, $errstr, $errfile, $errline)
    {
        if (!(error_reporting() & $errno)) {
            // This error code is not included in error_reporting, so let it fall
            // through to the standard PHP error handler
            return false;
        }

        switch ($errno) {
        case E_USER_ERROR:
            echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
            echo "  Fatal error on line $errline in file $errfile";
            echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
            echo "Aborting...<br />\n";
            exit(1);
            break;

        case E_USER_WARNING:
            echo "<b>My WARNING</b> [$errno] $errstr<br />\n";
            break;

        case E_USER_NOTICE:
            echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";
            break;

        default:
            echo "Unknown error type: [$errno] $errstr<br />\n";
            break;
        }

        /* Don't execute PHP internal error handler */
        return true;
    }

    // function to test the error handling
    function scale_by_log($vect, $scale)
    {
        if (!is_numeric($scale) || $scale <= 0) {
            trigger_error("log(x) for x <= 0 is undefined, you used: scale = $scale", E_USER_ERROR);
        }

        if (!is_array($vect)) {
            trigger_error("Incorrect input vector, array of values expected", E_USER_WARNING);
            return null;
        }

        $temp = array();
        foreach($vect as $pos => $value) {
            if (!is_numeric($value)) {
                trigger_error("Value at position $pos is not a number, using 0 (zero)", E_USER_NOTICE);
                $value = 0;
            }
            $temp[$pos] = log($scale) * $value;
        }

        return $temp;
    }

    // set to the user defined error handler
    $old_error_handler = set_error_handler("myErrorHandler");

    // trigger some errors, first define a mixed array with a non-numeric item
    echo "vector a\n";
    $a = array(2, 3, "foo", 5.5, 43.3, 21.11);
    print_r($a);

    // now generate second array
    echo "----\nvector b - a notice (b = log(PI) * a)\n";
    /* Value at position $pos is not a number, using 0 (zero) */
    $b = scale_by_log($a, M_PI);
    print_r($b);

    // this is trouble, we pass a string instead of an array
    echo "----\nvector c - a warning\n";
    /* Incorrect input vector, array of values expected */
    $c = scale_by_log("not array", 2.3);
    var_dump($c); // NULL

    // this is a critical error, log of zero or negative number is undefined
    echo "----\nvector d - fatal error\n";
    /* log(x) for x <= 0 is undefined, you used: scale = $scale" */
    $d = scale_by_log($a, -2.5);
    var_dump($d); // Never reached
    ?>

以上例程的输出类似于：

    vector a
    Array
    (
        [0] => 2
        [1] => 3
        [2] => foo
        [3] => 5.5
        [4] => 43.3
        [5] => 21.11
    )
    ----
    vector b - a notice (b = log(PI) * a)
    <b>My NOTICE</b> [1024] Value at position 2 is not a number, using 0 (zero)<br />
    Array
    (
        [0] => 2.2894597716988
        [1] => 3.4341896575482
        [2] => 0
        [3] => 6.2960143721717
        [4] => 49.566804057279
        [5] => 24.165247890281
    )
    ----
    vector c - a warning
    <b>My WARNING</b> [512] Incorrect input vector, array of values expected<br />
    NULL
    ----
    vector d - fatal error
    <b>My ERROR</b> [256] log(x) for x <= 0 is undefined, you used: scale = -2.5<br />
      Fatal error on line 35 in file trigger_error.php, PHP 5.2.1 (FreeBSD)<br />
    Aborting...<br />

### 参见

- ErrorException
- error_reporting() - 设置应该报告何种 PHP 错误
- restore_error_handler() - 还原之前的错误处理函数
- trigger_error() - 产生一个用户级别的 error/warning/notice 信息
- error level constants
- callback 类型的信息