Ykbug 2018-11-07
在php5.x中,如果想要最大程度的覆盖全局异常处理,需要通过下面三个方法实现
set_error_handler();
set_exception_handler();
register_shutdown_function();
set_error_handler
set_error_handler 用于自定义错误处理,但并不是全部的错误等级都能处理。
像E_ERROR,E_PARSE,E_CORE_ERRO, E_CORE_WARNING, E_COMPILE_ERROR,E_COMPILE_WARNING 这些错误等级是无法用该方法进行处理的。并且进行错误处理后,并不会终止脚本,而是会进行执行错误发生后面的脚本。如果需要终止脚本,可使用die或者exit等方法终止脚本
error_reporting(E_ALL);
set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) {
echo "set_error_handler: $errno,$errstr<br/>" ;
});
// 读取一个不存在的方法,会产生一个错误
readfile('not-exist-file');
// 产生一个用户级别的错误
trigger_error('tigger an error');
echo 'end of request' . PHP_EOL;
上面的代码会输出如下信息:
set_error_handler: 2,readfile(not-exist-file): failed to open stream: No such file or directory
set_error_handler: 1024,tigger an error
end of request
如果错误处理方法返回false,还会执行php的标准错误处理
set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) {
echo "set_error_handler: $errno,$errstr<br/>" ;
return false;
});
会产生如下信息
set_error_handler: 2,readfile(not-exist-file): failed to open stream: No such file or directory
Warning: readfile(not-exist-file): failed to open stream: No such file or directory in test.php on line 9
set_error_handler: 1024,tigger an error
Notice: tigger an error in test.php on line 11
end of request
set_exception_handler
set_exception_handler用于处理程序中未被处理的异常,并且在异常处理后,会中止脚本
set_exception_handler(function ($e) {
echo 'set_exception_handler:' . $e->getMessage() . PHP_EOL;
});
throw new Exception('exception msg');
echo 'end of request' . PHP_EOL;
以上代码会产生以下信息
set_exception_handler:exception msg
register_shutdown_function
register_shutdown_function注册的方法是在脚本运行完结的时候调用的,它不是直接用于错误处理,而是常常用于处理那些无法被set_error_handler处理的异常,通过error_get_last()方法,可以获取最后产生的错误。但是并不能覆盖php标准的错误处理方法。
set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) {
echo "set_error_handler: $errno,$errstr<br/>";
return false;
});
register_shutdown_function(function () {
$err = error_get_last();
if ($err) {
echo 'error:' . $err['message'];
}
});
// 调用不存在的方法
method_not_existed();
echo 'end of request' . PHP_EOL;
以上代码会产生以下信息
Fatal error: Call to undefined function method_not_existed() in test.php on line 30
error:Call to undefined function method_not_existed()
可以看到,调用一个不存在的方法时, 产生了一个Fatal error,这个等级的错误无法被set_error_handler处理,但可以在register_shutdown_function注册的方法中取得相应的异常。需要注意的是,信息的第一行是php标准错误处理方法输出的信息。
总结
php的全局异常/错误处理,通常需要通过set_error_handler,set_exception_handler,register_shutdown_function三个方法进行处理