PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。
这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获。如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。
Error 类并非继承自 Exception 类,所以不能用 catch (Exception $e) { ... }
来捕获 Error。你可以用 catch (Error $e) { ... }
,或者通过注册异常处理函数( set_exception_handler())来捕获 Error。
Error 层次结构 ¶
- Throwable
- Error
- ArithmeticError
- DivisionByZeroError
- AssertionError
- ParseError
- TypeError
- ArithmeticError
- Exception
- ...
- Error
在PHP5时,PHP是无法自动捕获异常的(绝大多数),只有主动抛出异常并捕捉。
现在在PHP7下你可以通过catch (Throwable) ,能自动捕获所有的异常和许多种错误。
如果再配合 set_error_handler();,基本上可以自动捕获所有的异常和错误。
代码如下:
try
{
// 写一些可能会抛出异常或错误的代码.
}
catch (Throwable $t)
{
// 只在php7下会执行,Php5下不会匹配。
}
注意:set_exception_handler()不再保证接收异常对象。
代码使用一个用set_exception_handler注册的用Exception 类型声明的异常处理程序,当Error对象抛出时会导致致命错误。
如果处理程序需要在PHP7和PHP5下同时能运行,你应该删除处理程序的类型声明, 而代码如果只在php7下运行只需要替换Exception类型声明为Throwable即可:
<?php
// PHP 5 时代代码会被打断.
function handler(Exception $e) { ... }
set_exception_handler('handler');
// PHP 5 和 PHP7 都兼容.
function handler($e) { ... }
// 仅PHP 7
function handler(Throwable $e) { ... }
?>
还有一些错误无法获得,怎么办呢,可通过用
register_shutdown_function
注册错误处理函数,然后 include的或 通过php.ini中设置
auto_prepend_file 或ob_start
可以获取错误
具体可参考
http://stackoverflow.com/questions/1900208/php-custom-error-handler-handling-parse-fatal-errors
http://stackoverflow.com/questions/277224/how-do-i-catch-a-php-fatal-error
https://trowski.com/2015/06/24/throwable-exceptions-and-errors-in-php7/
示例代码
<?php
// PHP 5 时代代码会被打断.
//function handler(Exception $e) { … }
set_exception_handler('handler');
set_error_handler("myErrorHandler");
register_shutdown_function('shutdown_function');
// PHP 5 和 PHP7 都兼容.
/*function handler($e) {
echo 'error!!!!!!';
}*/
// 仅PHP 7
function handler(Throwable $e) {
echo 'exception !!!!!!~';
echo $e->getMessage();
}
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
echo 'error!!!!';
}
function shutdown_function()
{
$e = error_get_last();
print_r($e);
}
fgfdg();
?>
ps: 异常和错误被捕获后,代码可以继续往下执行,但这取决于你执行在哪里,如下
try {
a();
b();
}
catch(Exception $e){
}
c();
如果a()抛出了一个异常,c()将会执行,但b()不会执行。
转载请注明来自Lenix的博客,地址http://blog.p2hp.com/archives/4211
最后更新于 2017年4月6日