在一个 catch 块中捕获多种异常类型 [英] Catching multiple exception types in one catch block

查看:25
本文介绍了在一个 catch 块中捕获多种异常类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like a cleaner way to obtain the following functionality, to catch AError and BError in one block:

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

有没有办法做到这一点?还是我必须分开捕捉它们?

Is there any way to do this? Or do I have to catch them separately?

AErrorBerror 有一个共享的基类,但它们也与其他类型共享它,我想通过 handler2>,所以我不能只抓基类.

AError and Berror have a shared base class, but they also share it with other types that I'd like to fall through to handler2, so I can't just catch the base class.

推荐答案

更新:

自 PHP 7.1 起,此功能可用.

Update:

As of PHP 7.1, this is available.

语法是:

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-294

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

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

不管这些其他答案怎么说,您可以在同一块中捕获 AErrorBError(如果您是定义异常的人,这会更容易一些).即使考虑到您想要通过"某些例外情况,您仍然应该能够定义一个层次结构来满足您的需求.

Despite what these other answers say, you can catch AError and BError in the same block (it is somewhat easier if you are the one defining the exceptions). Even given that there are exceptions you want to "fall through", you should still be able to define a hierarchy to match your needs.

abstract class MyExceptions extends Exception {}

abstract class LetterError extends MyExceptions {}

class AError extends LetterError {}

class BError extends LetterError {}

那么:

catch(LetterError $e){
    //voodoo
}

正如您在此处这里,即使 SPL 默认异常也有一个你可以利用的层次结构.此外,如PHP手册中所述:

As you can see here and here, even the SPL default exceptions have a hierarchy you can leverage. Additionally, as stated in the PHP Manual:

当抛出异常时,语句后面的代码不会被执行,并且PHP 将尝试找到第一个匹配的 catch 块.

When an exception is thrown, code following the statement will not be executed, and PHP will attempt to find the first matching catch block.

这意味着你也可以拥有

class CError extends LetterError {}

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

which you need to handle differently than AError or BError, so your catch statement would look like this:

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

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

If you had the case where there were twenty or more exceptions that legitimately belonged under the same superclass, and you needed to handle five (or whatever large-ish group) of them one way and the rest the other, you can STILL do this.

interface Group1 {}

class AError extends LetterError implements Group1 {}

class BError extends LetterError implements Group1 {}

然后:

catch (Group1 $e) {}

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

Using OOP when it comes to exceptions is very powerful. Using things like get_class or instanceof are hacks, and should be avoided if possible.

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

Another solution I would like to add is putting the exception handling functionality in its own method.

你本来可以

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

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

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

Assuming there is absolutely no way you can control exception class hierarchies or interfaces (and there almost always will be a way), you can do the following:

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 的一般结构中工作.

In this way, you are still have a only single code location you have to modify if your exception handling mechanism needs to change, and you are working within the general constructs of OOP.

这篇关于在一个 catch 块中捕获多种异常类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆