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

资源魔 27 0
媒介

比来名目中有一个性能需求完成:调试模式下, 将一切谬误提前输入, 再输入页面内容.

为完成上述性能, 需应用到Exception, Error相干Handler办法, 发现有许多坑, 故写此文与各人分享.

保举PHP视频教程:https://www.php.cn/course/list/29/type/2.html

次要函数

此篇文章重点存眷如下几个函数

一、error_reporting()

二、set_error_handler()

三、set_exception_handler()

四、register_shutdown_function()

五、error_get_last()

如下本文中重点解说成绩列表:

一、error_reporting() error_get_last() 有甚么联络?

二、set_error_handler() set_exception_handler() 绑定的handler何时才会启动? 它们有甚么联络?

三、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)

一、参数$error_types年夜多设定为error_reporting(), 但倡议设定为E_ALL, 详细哪些谬误需求被解决, 哪些没有需求, 正在handler内进行判别显著愈加灵敏.

二、如下级此外谬误不克不及由用户界说的函数来解决: E_ERROR E_PARSEE_CORE_ERRORE_CORE_WARNING E_COMPILE_ERRORE_COMPILE_WARNING,以及正在 挪用 set_error_handler() 函数所正在文件中孕育发生的年夜少数 E_STRICT

三、handler被触发后, 其实不会中缀PHP运转.

四、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列表

一、exception_handler 挪用后异样会停止(剧本终止).

二、PHP 5, PHP 7的exception_handler其实不相反.
PHP 5: void handler ( Exception $ex )
PHP 7: void handler ( Throwable $ex )

三、自 PHP 7 以来,年夜少数谬误抛出 Error 异样,也能被捕捉。 Error 以及 Exception 都完成了 Throwable 接口。

因而, set_error_handler() set_exception_handler() 之间的关系也迎刃而解:

PHP 5:

一、set_error_handler(): 担任非中缀行谬误.

二、set_exception_handler(): 担任不被catch的异样(会中缀).

三、Fatal Error等: 其实不会被二者治理, 失常输入到屏幕上(弊病).

PHP 7:

一、set_error_handler(): 担任非中缀行谬误.

二、set_exception_handler(): 担任不被catch的异样, Error(会中缀)

三、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;

以上就是全副内容了,更多相干成绩请拜访PHP中文网:https://www.php.cn/

以上就是对于PHP中Exception、Error Handler的细节和实例详解的具体内容,更多请存眷资源魔其它相干文章!

标签: php开发教程 php开发资料 php开发自学 exception

抱歉,评论功能暂时关闭!