比来名目中有一个性能需求完成:调试模式下, 将一切谬误提前输入, 再输入页面内容.
为完成上述性能, 需应用到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_PARSE
、 E_CORE_ERROR
、 E_CORE_WARNING
、 E_COMPILE_ERROR
、 E_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
抱歉,评论功能暂时关闭!