Maison > Questions et réponses > le corps du texte
J'aimerais un moyen plus propre d'obtenir les fonctionnalités suivantes à capturer dans un bloc AError
和 BError
:
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 ?
AError
和 Berror
有一个共享基类,但它们也与我想落入 handler2
est partagé par d'autres types, je ne peux donc pas simplement capturer la classe de base.
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 ); }
P粉6114563092023-10-15 00:46:51
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
Malgré ce que disent ces autres réponses, vous pouvez attraper AError
和 BError
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 SPL
par 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 AError
或 BError
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_class
或 instanceof
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.