Home > Article > Backend Development > Details and examples of Exception and Error Handler in PHP
Preface
There is a function that needs to be implemented in the recent project: in debugging mode, all errors are output in advance, and then the page content is output.
In order to realize the above function , you need to use Exception, Error related Handler methods, and found many pitfalls, so I wrote this article to share with you.
Recommended PHP video tutorial: //m.sbmmt.com/course/ list/29/type/2.html
##Main functions
This article focuses on the following functions1,error_reporting()
set_error_handler()
set_exception_handler()
register_shutdown_function()
error_get_last()
error_reporting() What is the connection with error_get_last() ?
set_error_handler() is bound to set_exception_handler() When will handler be started? How are they related?
register_shutdown_function() usually related to Exception/Error ?
Question solving:
1. What is the connection betweenerror_reporting() and error_get_last()?
php.net - error_reporting()link: <br>php.net - error_get_last()
int error_reporting ([ int $level ] )
array error_get_last (void)
<?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()Although it explains how to get the last error, it is actually the same. But it does not explain it and is error_reporting() Is it possible for ignored errors to be obtained? Therefore, when we use error_get_last(), we need to pay attention to the errors that are usually ignored, such as: E_DEPRECATED
set_error_handler() When will the handler bound to set_exception_handler() be started? What is their connection?
php.net - set_error_handler()link: <br>php.net - set_exception_handler()
mixed set_error_handler (callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
<br>
Usually triggered when some non-interruptive errors occur during the running of PHP scripts .We will use this to record error logs or direct output and other operations.<br>
Note:
FALSE: Standard error handling will still be performed (standard Error handling determines whether to output tostderr)1 based on display_errors = true/false
$error_types is mostly set to error_reporting(), but it is recommended to set it to E_ALL. It is obviously more flexible to judge which errors need to be processed and which ones do not need to be processed in the handler.
2、以下级别的错误不能由用户定义的函数来处理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT
3、handler被触发后, 并不会中断PHP运行.
4、bool error_handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )<br>注意error_handler的返回值:
b、callable set_exception_handler ( callable $exception_handler )
设置用户自定义的异常处理函数<br>设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止。
注意:
注意点中2, 3项轻描淡写了一下PHP 5/PHP 7之间的不同却透露出重要的消息(坑..)<br>PHP 7中, exception_handler 不再只接受Exception了, 并且接收了Error错误.<br>link: php.net - PHP7 Errors列表
1、exception_handler 调用后异常会中止(脚本终止).
2、PHP 5, PHP 7的exception_handler并不相同.<br>PHP 5: void handler ( Exception $ex )<br>PHP 7: void handler ( Throwable $ex )
3、自 PHP 7 以来,大多数错误抛出 Error 异常,也能被捕获。 Error 和 Exception 都实现了 Throwable 接口。
因此, set_error_handler() 与 set_exception_handler() 之间的关系也迎刃而解:<br>
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完全没关系.<br>提出这个问题, 主要是因为, 在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中更多的是一些版本冗余的工作.<br>
实例
前言中的需求: 调试模式下, 将所有错误提前输出, 再输出页面内容.<br>以下是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中文网://m.sbmmt.com/<br>
The above is the detailed content of Details and examples of Exception and Error Handler in PHP. For more information, please follow other related articles on the PHP Chinese website!