我正在深化PHP异常。此代码在php7 上运行
class MyErrorException extends ErrorException
{ /* stuff here */}
function uncaught_exception_handler($exception)
{ /* stuff here */ }
function uncaught_error_handler()
{ /* throws new MyErrorException */ }
set_exception_handler('uncaught_exception_handler');
set_error_handler('uncaught_error_handler');
$analyze_case = function($e)
{
switch (get_class($e)){
case 'Exception':
echo "I've caught an Exception" . PHP_EOL;
break;
case 'Error':
echo "I've caught an Error" . PHP_EOL;
break;
case 'ErrorException':
echo "I've caught an ErrorException" . PHP_EOL;
break;
case 'MyErrorException':
echo "I've caught a MyErrorException" . PHP_EOL;
break;
default:
echo "I've caught something: " . get_class($e) . PHP_EOL;
break;
}
};
echo "Case 8" . PHP_EOL;
try {
throw new MyErrorException();
} catch (Exception $e) {
echo "I've caught an Exception" . PHP_EOL;
} catch (ErrorException $e) {
echo "I've caught an ErrorException" . PHP_EOL;
} catch (MyErrorException $e) {
echo "I've caught a MyErrorException" . PHP_EOL;
} catch (Error $e) {
echo "I've caught an Error" . PHP_EOL;
}
echo "Case 9" . PHP_EOL;
try {
throw new MyErrorException();
} catch (Exception $e) {
$analyze_case($e);
};
echo "Case 10" . PHP_EOL;
try {
throw new MyErrorException();
} catch (MyErrorException $e) {
echo "I've caught a MyErrorException" . PHP_EOL;
} catch (Exception $e) {
echo "I've caught an Exception" . PHP_EOL;
} catch (ErrorException $e) {
echo "I've caught an ErrorException" . PHP_EOL;
} catch (Error $e) {
echo "I've caught an Error" . PHP_EOL;
}
以下是结果:
Case 8
I've caught an Exception
Case 9
I've caught a MyErrorException
Case 10
I've caught a MyErrorException
我不明白:
- 为什么情况8和10不匹配
- 更具体地说,为什么在情况8)中抛出的异常没有被
catch (MyErrorException $e)
块捕获
案例8
在情况8中,第一个catch块捕获您的异常,因为您的异常类MyErrorException
从ErrorException
扩展而来,而这是从Exception
扩展而来的。所以它已经在第一个接球块中被抓住了。
注意:您的异常可能会被MyErrorException
、ErrorException
和Exception
捕获,因为它是所有这些类的一部分。但Error
无法捕捉到。
案例9
同样,在情况9中,它会被捕获,因为它也是一个Exception
,但由于您在交换机状态中检查了类,所以您得到了MyErrorException
。因为您有一个MyErrorException
异常。
案例10
在情况10中,它与8中相同,只是MyErrorException
现在首先捕获异常,而不是Exception
。
如果我没有弄错,在情况8中,您会得到一条I've caught an Exception
消息,因为您的MyErrorException
(间接)继承自Exception
。抛出的对象是Exception
的实例,执行第一个catch块。
如果您想为Exception
的子类提供特定的catch块,那么应该将它们放在第一位。