这个PHP异常混淆了try..catch嵌套

Dom*_*nic 14 php exception-handling

我对以下代码感到困惑:

class MyException extends Exception {}
class AnotherException extends MyException {}

class Foo {
  public function something() {
    print "throwing AnotherException\n";
    throw new AnotherException();
  }
  public function somethingElse() {
    print "throwing MyException\n";
    throw new MyException();
  }
}

$a = new Foo();

try {
  try {
    $a->something();    

  } catch(AnotherException $e) {
    print "caught AnotherException\n";
    $a->somethingElse();    
  } catch(MyException $e) {
    print "caught MyException\n";
  }
} catch(Exception $e) {
  print "caught Exception\n";
}
Run Code Online (Sandbox Code Playgroud)

我希望这会输出:

throwing AnotherException
caught AnotherException
throwing MyException
caught MyException
Run Code Online (Sandbox Code Playgroud)

但相反它输出:

throwing AnotherException
caught AnotherException
throwing MyException
caught Exception
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么它"跳过"捕获(MyException $ e)?

谢谢.

Odd*_*ing 17

异常处理程序捕获由try块范围内的代码引发的异常.

调用$a->somethingElse()不会发生在与跳过的异常处理程序关联的try块中.它发生在另一个catch子句中.

仅仅因为它看起来物理上低于引发异常的行,这不足以使它覆盖该代码.

缩进括号的样式选择使这不太清楚,恕我直言.前一个try块的close括号出现在与下一个catch相同的行上,即使它们是不相关的(好的,兄弟)范围.


the*_*iko 6

只是因为评论中没有足够的空间.想想try ... catch作为if ... else循环.您不会期望以下内容:

$a = 10;
if($a == 9)
    print "\$a == 9";
elseif($a == 10) {
    $a = 11;
    echo "now \$a == 11";
} elseif($a == 11) {
    echo "\$a == 11";
}
Run Code Online (Sandbox Code Playgroud)

打印出最后一个条件("\ $ a == 11"),因为条件已经满足第一个条件elseif.try ... catch也是如此.如果满足条件,则不会继续在同一范围内搜索新条件.