1 つの catch ブロックで複数の例外タイプをキャッチする 質問する

1 つの catch ブロックで複数の例外タイプをキャッチする 質問する

AError次の機能をキャッチしてBError1 つのブロックで取得するためのよりクリーンな方法が必要です。

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

これを実行する方法はありますか? それとも別々にキャッチする必要がありますか?

AError共通の基本クラスがありますBerrorが、フォールスルーしたい他の型とも共有しているためhandler2、基本クラスをキャッチすることはできません。

ベストアンサー1

アップデート:

PHP 7.1 以降ではこれが利用可能です。

構文は次のとおりです。

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

ドキュメント:https://www.php.net/manual/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 より前のバージョンの場合:

他の回答が言っていることにもかかわらず、同じブロック内で catchAErrorとcatchBErrorを実行できます (例外を定義する側であれば、多少簡単です)。「フォールスルー」したい例外がある場合でも、ニーズに合わせて階層を定義できるはずです。

abstract class MyExceptions extends Exception {}

abstract class LetterError extends MyExceptions {}

class AError extends LetterError {}

class BError extends LetterError {}

それから:

catch(LetterError $e){
    //voodoo
}

ご覧のようにここそしてここデフォルトの例外にもSPL活用できる階層があります。さらに、PHPマニュアル:

例外がスローされると、ステートメントに続くコードは実行されず、PHP は最初に一致する catch ブロックを見つけようとします。

つまり、

class CError extends LetterError {}

AErrorこれは、またはとは異なる方法で処理する必要があるBErrorため、catch ステートメントは次のようになります。

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

同じスーパークラスに正当に属する例外が 20 個以上あり、そのうちの 5 個 (または比較的大きなグループ) をある方法で処理し、残りを別の方法で処理する必要がある場合でも、これを実行できます。

interface Group1 {}

class AError extends LetterError implements Group1 {}

class BError extends LetterError implements Group1 {}

その後:

catch (Group1 $e) {}

例外に関して OOP を使用すると非常に強力です。get_classやなどの使用はinstanceofハックであり、可能であれば避けるべきです。

追加したいもう 1 つの解決策は、例外処理機能を独自のメソッドに配置することです。

あなたは

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);
}

この方法では、例外処理メカニズムを変更する必要がある場合でも、変更する必要があるコードの場所は 1 つだけであり、OOP の一般的な構造内で作業することになります。

おすすめ記事