合并多个异常类型在一个catch块中
P粉547420474
P粉547420474 2023-10-14 16:57:18
0
2
539

我想要一种更简洁的方法来获取以下功能,以在一个块中捕获 AErrorBError

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

有什么办法可以做到这一点吗?还是我必须单独捕获它们?

AErrorBerror 有一个共享基类,但它们也与我想落入 handler2 的其他类型共享,所以我不能只捕获基类。

P粉547420474
P粉547420474

全部回复(2)
P粉777458787

在 PHP >= 7.1 中这是可能的。请参阅此答案


如果您可以修改例外情况,请使用此答案

如果不能,您可以尝试使用 Exception 捕获所有异常,然后使用 instanceof

try
{
    /* something */
}
catch( Exception $e )
{
    if ($e instanceof AError OR $e instanceof BError) {
       // It's either an A or B exception.
    } else {
        // Keep throwing it.
        throw $e;
    }
}

但是最好使用多个catch块,如上述答案中所述 .

try
{
    /* something */
}
catch( AError $e )
{
   handler1( $e );
}
catch ( BError $b )
{
   handler2( $e );
}
P粉611456309

更新:

从 PHP 7.1 开始,此功能可用。

语法是:

try
{
    // Some code...
}
catch(AError | BError $e)
{
    // Handle exceptions
}
catch(Exception $e)
{
    // Handle the general case
}

文档:https://www.php.net/手册/en/language.exceptions.php#example-334

RFC:https://wiki.php.net/rfc/multiple-catch

提交:https://github.com/php/php-src/commit/ 0aed2cc2a440e7be17552cc669d71fdd24d1204a


对于 PHP 7.1 之前的版本:

不管这些其他答案怎么说,您都可以在同一个块中捕获 AErrorBError (如果您是定义异常的人,那就更容易了)。即使存在您希望“排除”的例外情况,您仍然应该能够定义层次结构来满足您的需求。

abstract class MyExceptions extends Exception {}

abstract class LetterError extends MyExceptions {}

class AError extends LetterError {}

class BError extends LetterError {}

然后:

catch(LetterError $e){
    //voodoo
}

如您所见此处此处,即使是 SPL 默认异常也有一个可以利用的层次结构。此外,如 PHP 手册中所述:

这意味着您也可以拥有

class CError extends LetterError {}

您需要以不同于 AErrorBError 的方式处理它,因此您的 catch 语句将如下所示:

catch(CError $e){
    //voodoo
}
catch(LetterError $e){
    //voodoo
}

如果您遇到这样的情况,其中有二十个或更多合法属于同一超类的异常,并且您需要以一种方式处理其中五个(或任何大型组),而其余的则以另一种方式处理,您仍然可以这样做。

interface Group1 {}

class AError extends LetterError implements Group1 {}

class BError extends LetterError implements Group1 {}

然后:

catch (Group1 $e) {}

在处理异常时使用 OOP 非常强大。使用诸如 get_classinstanceof 之类的东西都是黑客行为,应该尽可能避免。

我想添加的另一个解决方案是将异常处理功能放入其自己的方法中。

你可以有

function handleExceptionMethod1(Exception $e)
{
    //voodoo
}

function handleExceptionMethod2(Exception $e)
{
    //voodoo
}

假设您绝对没有办法控制异常类层次结构或接口(并且几乎总是会有办法),您可以执行以下操作:

try
{
    stuff()
}
catch(ExceptionA $e)
{
    $this->handleExceptionMethod1($e);
}
catch(ExceptionB $e)
{
    $this->handleExceptionMethod1($e);
}
catch(ExceptionC $e)
{
    $this->handleExceptionMethod1($e);
}
catch(Exception $e)
{
    $this->handleExceptionMethod2($e);
}

通过这种方式,如果您的异常处理机制需要更改,您仍然只有一个必须修改的代码位置,并且您正在 OOP 的一般构造内工作。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!