Kombinieren Sie mehrere Ausnahmetypen in einem Catch-Block
P粉547420474
P粉547420474 2023-10-14 16:57:18
0
2
610

Ich hätte gerne eine sauberere Möglichkeit, die folgenden Funktionen in einem Block zu erfassen AErrorBError:

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

Gibt es eine Möglichkeit, dies zu tun? Oder muss ich sie einzeln erfassen?

AErrorBerror 有一个共享基类,但它们也与我想落入 handler2 wird von anderen Typen gemeinsam genutzt, daher kann ich nicht einfach die Basisklasse erfassen.

P粉547420474
P粉547420474

Antworte allen(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 的一般构造内工作。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage