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
    • Exception
      • ...

在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日

PHP 7 的异常和错误处理
标签: