我想用一种更干净的方式来获得以下功能,在一个块中捕获AError和BError:

try
{
    /* something */
}
catch( AError, BError $e )
{
    handler1( $e )
}
catch( Exception $e )
{
    handler2( $e )
}

有什么办法可以做到吗?还是我得分别抓他们?

AError和Berror有一个共享的基类,但它们还与我希望落入handler2的其他类型共享这个基类,因此不能只捕获基类。


当前回答

如果您无法控制异常的定义,这里有一个合理的替代方案。在捕获异常时,使用异常变量的名称对异常进行分类。然后在try/catch块之后检查异常变量。

$ABError = null;
try {
    // something
} catch (AError $ABError) {  // let the exception fall through
} catch (BError $ABError) {  // let the exception fall through
} catch (Exception $e) {
    handler2($e);
}
if ($ABError) {
    handler1($ABError);
}

这种看起来有点奇怪的方法可能只在catch块实现之间存在大量重复的情况下才有价值。

其他回答

除了穿越,也可以使用goto跨过去。 如果你想看世界燃烧,这很有用。

<?php

class A_Error extends Exception {}
class B_Error extends Exception {}
class C_Error extends Exception {}

try {
    throw new A_Error();
} 
catch (A_Error $e) { goto abc; }
catch (B_Error $e) { goto abc; }
catch (C_Error $e) {
abc:
    var_dump(get_class($e));
    echo "Gotta Catch 'Em All\n";
}

3 v4l.org

从PHP 8.0开始,当您不需要输出错误内容(从变量$e)时,您可以使用更清晰的方式来捕获异常。但是你必须用Throwable替换默认的Exception。

try {
    /* something */
} catch (AError | BError) {
    handler1()
} catch (Throwable) {
    handler2()
}

一个很好的方法是使用set_exception_handler。

警告! !在PHP 7中,如果出现致命错误,可能会出现死机白屏。例如,如果你在一个非对象上调用一个方法,你通常会得到致命错误:在null上调用成员函数your_method(),如果错误报告是打开的,你会期望看到这个。

上面的错误不会被catch捕获(异常$e)。 上述错误不会触发set_error_handler设置的任何自定义错误处理程序。

你必须使用catch(Error $e){}来捕获PHP7中的错误。 这可能会有所帮助:

class ErrorHandler{
    public static function excep_handler($e)
    {
        print_r($e);
    }
}
set_exception_handler(array('ErrorHandler','excep_handler'));

嗯,有很多解决方案是为低于7.1的php版本编写的。

下面是另一个简单的方法,适用于那些不想catch all异常且不能创建公共接口的人:

<?php
$ex = NULL
try {
    /* ... */
} catch (FirstException $ex) {
    // just do nothing here
} catch (SecondException $ex) {
    // just do nothing here
}
if ($ex !== NULL) {
    // handle those exceptions here!
}
?>

从PHP 7.1开始,

catch( AError | BError $e )
{
    handler1( $e )
}

有趣的是,你还可以:

catch( AError | BError $e )
{
    handler1( $e )
} catch (CError $e){
    handler2($e);
} catch(Exception $e){
    handler3($e);
}

在PHP的早期版本中:

catch(Exception $ex){
    if($ex instanceof AError || $ex instanceof BError){
        //handle AError and BError
    } elseif($ex instanceof CError){
        //handle CError
    } else {
       throw $ex; // an unknown exception occurred, throw it further
    }
}