旗下导航:搜·么
当前位置:网站首页 > PHP教程 > 正文

关于PHP中Exception、Error Handler的细节以及实例详解【php教程】

作者:搜搜PHP网发布时间:2019-11-26分类:PHP教程浏览:102


导读:媒介近来项目中有一个功用须要完成:调试形式下,将一切毛病提早输出,再输出页面内容.为完成上述功用,需运用到Exception,Error相干Handler要领,...
媒介

近来项目中有一个功用须要完成:调试形式下, 将一切毛病提早输出, 再输出页面内容.

为完成上述功用, 需运用到Exception, Error相干Handler要领, 发现有很多坑, 故写此文与人人分享.

引荐PHP视频教程:https://www.ki4.cn/course/list/29/type/2.html

主要函数

此篇文章重点关注以下几个函数

1、error_reporting()

2、set_error_handler()

3、set_exception_handler()

4、register_shutdown_function()

5、error_get_last()

以下本文中重点解说题目列表:

1、error_reporting() error_get_last() 有什么联络?

2、set_error_handler() set_exception_handler() 绑定的handler什么时候才会启动? 它们有什么联络?

3、register_shutdown_function()一般跟Exception/Error有关联么?

解疑:

1. error_reporting()error_get_last() 有什么联络?

link: php.net - error_reporting()
link: php.net - error_get_last()

a:int error_reporting ([ int $level ] )

人人应该再熟习不过了, 因而不再赘述.

b:array error_get_last ( void )

猎取末了发作的毛病

一般用来猎取PHP运转过程当中的Fatal Error毛病(PHP 5).

这两个函数在字面上关联性并不强, 但请视察以下代码及输出

<?php
error_reporting(E_ALL & ~E_NOTICE);
$a = $b;  //E_NOTICEprint_r(error_get_last());/* output:
Array
(
    [type] => 8
    [message] => Undefined variable: b
    [file] => /app/t.php
    [line] => 3
)
*/

error_get_last()虽然说清楚明了猎取末了发作的毛病, 实际上也是云云. 但却没有申明, 被error_reporting()疏忽掉的毛病是不是有能够被猎取到, 因而, 当我们运用error_get_last()时须要注重日常平凡疏忽掉的毛病, 如: E_DEPRECATED

2. set_error_handler()set_exception_handler() 绑定的handler什么时候才会启动? 它们有什么联络?

link: php.net - set_error_handler()
link: php.net - set_exception_handler()

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

设置用户自定义的毛病处置惩罚函数

一般在PHP剧本运转过程当中, 涌现一些非中断性毛病时触发.
我们会用这个来纪录毛病日记或直接输出等操纵.

注重:

FALSE: 规范的毛病处置惩罚依旧会被实行(规范毛病处置惩罚依据 display_errors = true/false 决议是不是输出到stderr)

1、参数$error_types大多设定为error_reporting(), 但发起设定为E_ALL, 细致哪些毛病须要被处置惩罚, 哪些不须要, 在handler内举行推断显著越发天真.

2、以下级别的毛病不能由用户定义的函数来处置惩罚: E_ERROR E_PARSEE_CORE_ERRORE_CORE_WARNING E_COMPILE_ERRORE_COMPILE_WARNING,和在 挪用 set_error_handler() 函数所在文件中发生的大多数 E_STRICT

3、handler被触发后, 并不会中断PHP运转.

4、bool error_handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )
注重error_handler的返回值:

b、callable set_exception_handler ( callable $exception_handler )

设置用户自定义的非常处置惩罚函数
设置默许的非常处置惩罚顺序,用于没有用 try/catch 块来捕获的非常。 在 exception_handler 挪用后非常会中断。

注重:

注重点中2, 3项轻描淡写了一下PHP 5/PHP 7之间的差别却透露出主要的音讯(坑..)
PHP 7中, exception_handler 不再只吸收Exception了, 而且吸收了Error毛病.
link: php.net - PHP7 Errors列表

1、exception_handler 挪用后非常会中断(剧本停止).

2、PHP 5, PHP 7的exception_handler并不相同.
PHP 5: void handler ( Exception $ex )
PHP 7: void handler ( Throwable $ex )

3、自 PHP 7 以来,大多数毛病抛出 Error 非常,也能被捕获。 Error Exception 都完成了 Throwable 接口。

因而, set_error_handler() set_exception_handler() 之间的关联也水到渠成:

PHP 5:

1、set_error_handler(): 担任非中断行毛病.

2、set_exception_handler(): 担任没有被catch的非常(会中断).

3、Fatal Error等: 并不会被二者治理, 一般输出到屏幕上(弊病).

PHP 7:

1、set_error_handler(): 担任非中断行毛病.

2、set_exception_handler(): 担任没有被catch的非常, Error(会中断)

3、Fatal Error等: 由set_exception_handler()治理.

3. register_shutdown_function()一般跟Exception/Error有关联么?

link: php.net - register_shutdown_function()

注册一个 callback ,它会在剧本实行完成或许 exit() 后被挪用。

依据申明能够得出结论, 它与Exception/Error完整没紧要.
提出这个题目, 主要是因为, 在PHP5中Fatal Error并没有明白的吸收所在, 所以我们一般合营error_get_last()来吸收Fatal Error

<?php 
register_shutdown_function('shutdown_function');
unknown_function();function shutdown_function() {
  print_r(error_get_last());
}/* output:Array(
    [type] => 1
    [message] => Uncaught Error: Call to undefined function unknown_function() in /app/t.php:3Stack trace:#0 {main}
  thrown
    [file] => /app/t.php
    [line] => 3)
*/

但是跟着PHP 7的到来, Error已能够被set_exception_handler()捕获了, 再经由过程error_get_last()就过剩了. shutdown中更多的是一些版本冗余的事变.

实例

媒介中的需求: 调试形式下, 将一切毛病提早输出, 再输出页面内容.
以下是demo, 省去了环境推断(debug环境), 人人能够依据下面这段代码, 相识本文中所说的种种handler的触发和挪用状况.

<?php/*
请求: 将一切非常打印在屏幕最上方
*//* Fatal Error 中断剧本 -> shutdown_handler *///设置毛病级别define("END_ERRORS", '--END ERRORS--' . PHP_EOL . PHP_EOL);
ini_set('display_errors', true);
ini_set('error_reporting', E_ALL & ~E_DEPRECATED);

set_error_handler('usr_err_handler', error_reporting()); //注册毛病处置惩罚函数set_exception_handler('usr_ex_handler'); //注册非常处置惩罚函数register_shutdown_function('shutdown_handler');    //注册会在php中断时实行的函数$global_errors = [];    //用于纪录一切毛病$errnos = [             //毛病级别
    0 => 'ERROR',//PHP7 ERROR的CODE
    1 => 'E_ERROR',//FATAL ERROR(PHP5), E_ERROR
    2 => 'E_WARNING',    4 => 'E_PARSE',    8 => 'E_NOTICE',    16 => 'E_CORE_ERROR',    32 => 'E_CORE_WARNING',    64 => 'E_COMPILE_ERROR',    128 => 'E_COMPILE_WARNING',    256 => 'E_USER_ERROR',    512 => 'E_USER_WARNING',    1024 => 'E_USER_NOTICE',    2048 => 'E_STRICT',    4096 => 'E_RECOVERABLE_ERROR',    8192 => 'E_DEPRECATED',    16384 => 'E_USER_DEPRECATED',    30719 => 'E_ALL',
];function reset_errors(){    global $global_errors;
    $global_errors = [];
}function get_errnostr($errno){    global $errnos;    return $errnos[$errno];
}function set_errnos($errno, $errstr){    global $global_errors;
    $global_errors[] = [        'errno' => $errno,        'errnostr' => get_errnostr($errno),        'errstr' => $errstr,
    ];
}function print_errors($prefix){    global $global_errors;    foreach ($global_errors as $err) {//因为handler中依旧有能够有error 因而放末了
        printf("[%s]: %s, %d, %s\n",
            $prefix, $err['errnostr'], $err['errno'], $err['errstr']);
    }
}//用户非常处置惩罚函数 (进来就中断剧本) PHP5只要Exception进来   PHP7Error和Exception//PHP7中 void handler (Throwable $ex) 可捕获Error和Exception两种非常, 暂不论//http://php.net/manual/en/language.errors.php7.php PHP7 Error浏览//内部假如有Error则触发Error函数, 再回到毛病行继承实行function usr_ex_handler($ex){
    $content = ob_get_clean();  //让Exception/Error提早展现

    print_errors('EX ERROR');
    reset_errors();

    $errnostr = get_errnostr($ex->getCode());
    $errno = $ex->getCode();
    $errstr = $ex->getMessage();    if ($ex instanceof Exception) {
        printf("[EXCEPTION]: %s, %d, %s\n", $errnostr, $errno, $errstr);
    } else {//针对PHP7  $ex instanceof Error
        printf("[EX FATAL ERROR]: %s, %d, %s\n", $errnostr, $errno, $errstr);
    }    //因为handler中依旧有能够有error 因而放末了
    print_errors('EX ERROR');
    reset_errors();    echo END_ERRORS;    echo $content;    return;
}//用户毛病处置惩罚函数//E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING不能被用户处置惩罚function usr_err_handler($errno, $errstr, $errfile, $errline, $errcontext){
    set_errnos($errno, $errstr);    return true;    //假如函数返回 FALSE,规范毛病处置惩罚处置惩罚顺序将会继承挪用。}//用户PHP停止函数function shutdown_handler(){
    $content = ob_get_clean();  //让Exception/Error提早展现
    $err = error_get_last();//检查一下是不是有遗漏掉的毛病 php5 fatal error
    if ($err['type'] & error_reporting()) {
        set_errnos($err['type'], $err['message']);
    }
    print_errors('ST ERROR');
    reset_errors();    echo $content;
}

ob_start();echo 'Main function...', PHP_EOL;//搞事变//throw new Exception('这是一个非常');trigger_error('这是一个用户error');//E_USER_NOTICEif (version_compare(PHP_VERSION, '7.0.0') >= 0) {
    mcrypt_encrypt();//E_WARNING, E_DEPRECATED} else {
    mysql();
}
unknown_function(); //fatal error$content = ob_get_clean();//优先输出毛病print_errors('MA ERROR');if (!empty($global_errors)) {    echo END_ERRORS;
}
reset_errors();//输出正文内容echo $content;

以上就是全部内容了,更多相干题目请接见ki4网:https://www.ki4.cn/

以上就是关于PHP中Exception、Error Handler的细节以及实例详解的细致内容,更多请关注ki4网别的相干文章!

标签:exception