PHP 异常 类 中的反向级联?

Reverse Cascade in PHP Exception Classes?

我只是想仔细检查一下我刚刚发现的是否是默认的 PHP 行为,因为否则我无法解释。假设您构建了自定义 PHP Exceptions class:

<?php
namespace XYZ;

if ( ! class_exists( 'XYZ\CustomException' ) ) {

  class CustomException extends \Exception {

    public function __construct( int $code ) {

        parent::__construct( "The error code is: $code", $code );

    }

  }

}
?>

然后您启动一个 PHP 脚本,其内容如下:

try {
  throw new CustomException(1);
} catch ( \Exception $e ) {
  echo "regular exception thrown";
} catch ( CustomException $e ) {
  echo "custom exception thrown";
}

当运行那个块时,我得到"regular exception thrown"

当我将脚本的 catch 块反转为:

try {
  throw new CustomException(1);
} catch ( CustomException $e ) {
  echo "custom exception thrown";
} catch ( \Exception $e ) {
  echo "regular exception thrown";
} 

我得到 "custom exception thrown"

PHP Exception class 的子 class 是否会被父 Exception 处理器捕获,如果parent Exception class catch块先写??或者这是某种不寻常的奇怪配置?

这是正常行为。因为你的 CustomException 继承了 Exception 而你的第一个 catch 反对 Exception 它会先停在这里。

当抛出异常时,依次经过try块,检测异常是否为指定class的实例,遇到第一个匹配就停止堵塞。由于 CustomExceptionException 的子 class,catch ( \Exception ) 块匹配此测试,因此它先停在那里。

本质上是这样的:

if (is_a($e, 'Exception')) {
    echo "regular exception thrown";
} elseif (is_a($e, 'CustomException')) {
    echo "custom exception thrown";
}

它不会尝试找到具有最接近匹配的 catch 块,它只是按顺序完成。您有责任按具体顺序订购它们。

documentation 对此进行了解释:

The first catch block a thrown exception or error encounters that matches the type of the thrown object will handle the object.