Maison  >  Questions et réponses  >  le corps du texte

Combiner plusieurs types d'exceptions dans un bloc catch

J'aimerais un moyen plus propre d'obtenir les fonctionnalités suivantes à capturer dans un bloc AErrorBError :

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

Y a-t-il un moyen de procéder ? Ou dois-je les capturer individuellement ?

AErrorBerror 有一个共享基类,但它们也与我想落入 handler2 est partagé par d'autres types, je ne peux donc pas simplement capturer la classe de base.

P粉547420474P粉547420474388 Il y a quelques jours600

répondre à tous(2)je répondrai

  • P粉777458787

    P粉7774587872023-10-15 15:07:15

    C'est possible en PHP >= 7.1. Voir cette réponse.


    Si vous pouvez modifier l'exception, veuillez utiliser cette réponse.

    Sinon, vous pouvez essayer d'utiliser 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;
        }
    }

    Mais il vaut mieux utiliser plusieurs blocs catch comme mentionné dans la réponse ci-dessus .

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

    répondre
    0
  • P粉611456309

    P粉6114563092023-10-15 00:46:51

    Mise à jour :

    Cette fonctionnalité est disponible à partir de PHP 7.1.

    La syntaxe est :

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

    Documentation : https://www.php.net/manual/en/langue.exceptions.php#example-334

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

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


    Pour les versions antérieures à PHP 7.1 :

    Malgré ce que disent ces autres réponses, vous pouvez attraper AErrorBError dans le même bloc (c'est plus facile si c'est vous qui définissez l'exception). Même s'il existe des exceptions que vous souhaitez « exclure », vous devriez toujours pouvoir définir la hiérarchie en fonction de vos besoins.

    abstract class MyExceptions extends Exception {}
    
    abstract class LetterError extends MyExceptions {}
    
    class AError extends LetterError {}
    
    class BError extends LetterError {}

    Puis :

    catch(LetterError $e){
        //voodoo
    }

    Comme vous pouvez le voir iciet ici, même l'exception SPLpar défaut a une hiérarchie qui peut être exploitée. De plus, comme indiqué dans le Manuel PHP :

    Cela signifie que vous pouvez l'avoir aussi

    class CError extends LetterError {}

    Vous devez le gérer différemment de AErrorBError donc votre déclaration catch ressemblera à ceci :

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

    Si vous vous trouvez dans une situation où il y a vingt exceptions ou plus qui appartiennent légitimement à la même superclasse, et que vous devez en gérer cinq (ou tout grand groupe) d'une manière et le reste d'une autre manière, vous pouvez toujours le faire.

    interface Group1 {}
    
    class AError extends LetterError implements Group1 {}
    
    class BError extends LetterError implements Group1 {}

    Puis :

    catch (Group1 $e) {}

    Utiliser la POO lors de la gestion des exceptions est très puissant. Utiliser des choses comme get_classinstanceof est un hack et doit être évité si possible.

    Une autre solution que j'aimerais ajouter est de placer la fonctionnalité de gestion des exceptions dans sa propre méthode.

    Vous pouvez l'avoir

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

    En supposant que vous n'avez absolument aucun moyen de contrôler la hiérarchie ou l'interface des classes d'exception (et presque toujours il y aura un moyen), vous pouvez procéder comme suit :

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

    De cette façon, si votre mécanisme de gestion des exceptions doit changer, vous n'avez toujours qu'un seul emplacement de code à modifier et vous travaillez dans la construction générale de la POO.

    répondre
    0
  • Annulerrépondre