6.Le langage PHP

6.8.Programmation orientée objet

6.8.3.Les exceptions

6.8.3.1.Introduction

Comme pour tout langage de programmation orienté objet, les classes PHP sont susceptibles de lever des exceptions (i.e. des erreurs). PHP propose donc les structures de contrôle adaptées à leur gestion.
En bref:
<?php
try {
    $objet->nomMethode($param);
    echo 'Ligne non executée si nomMethode() lève une exception'."\n";
} catch (NomException $e) {
    // Bout de code exécuté si une exception NomException est levée
    // l'exception est stockée dans $e
    echo 'L\'appel à nomMethode a levé une erreur'.$e->getMessage().
         ' de code '.$e->getCode()."\n";
    echo 'En voici le détail :'.$e->getTraceAsString();
} catch (AutreNomException $e) {
    // Et si l'on souhaite nous même lever une Exception
    $codeErreur = 25;
    throw new Exception('Ca ne va pas....', $codeErreur);
} finally {
    // Bout de code a exécuter quoiqu'il arrive (éventuellement après
    // l'exécution d'un bloc catch) à condition d'avoir PHP 5.5 au moins
}

6.8.3.2.try ... catch

Une exception est un objet qui hérite de la classe de base Exception. Elle peut être initiée à tout moment de l'exécution d'un code (typiquement lorsqu'une erreur est détectée). Lorsqu'une exception est levée, l'exécution du code est interrompu, la pile des appels de fonctions est dépilée jusqu'à trouver une fonction appelante qui intercepte cette exception.
L'interception des exceptions se fait avec un bloc try...catch selon le modèle.
<?php
try {
    $objet->nomMethode($param);
    echo 'Ligne non executée si nomMethode() lève une exception'."\n";
} catch (NomException $e) {
    // l'objet $e peut alors être manipulé dans ce bloc
}
La variable précisée dans la ligne "catch" (ici $e, comme on a souvent l'habitude de noter) contient alors l'objet exception. Et c'est dans le bloc "catch" que l'on doit préciser les opérations à réaliser en cas de levée d'exception (dans notre exemple ceci ne concerne que les exceptions héritant de NomException, les autres exceptions ne seront pas traitées ou alors par une des fonctions appelantes).
Si l'on souhaite véritablement traiter indifféremment l'ensemble des exceptions, on pourra écrire
<?php
try {
    $objet->nomMethode($param);
    echo 'Ligne non executée si nomMethode() lève une exception'."\n";
} catch (Exception $e) {
    // l'objet $e peut alors être manipulé dans ce bloc
}
Mais dans la pratique, les réponses à apporter peuvent varier selon le type d'exception, il est alors possible d'enchaîner les blocs "catch" selon le modèle suivant:
<?php
try {
    $objet->nomMethode($param);
} catch (PasTrouveException $e) {
    // Si la méthode retourne une exception "PasTrouveException"
    // c'est ce bloc qui est exécuté
} catch (ParametreInvalideException $e) {
    // Si la méthode retourne une exception "ParametreInvalideException"
    // c'est ce bloc qui est exécuté
}

6.8.3.3.finally

Il est parfois nécessaire d'exécuter un bout de code, en toutes circonstances, qu'une exception ait été levée ou pas. Pour cela, il y a, depuis PHP 5.5, l'instruction finally.
<?php
try {
    $objet->nomMethode($param);
    echo 'Ligne non executée si nomMethode() lève une exception'."\n";
} finally {
    // bloc exécuté coûte que coûte (le cas échéant après le bloc "catch")
}

6.8.3.4.throw

Si vous souhaitez vous-même lever une exception sachez que vous disposez de l'instruction throw qu'il suffit de faire suivre d'un objet Exception (ou héritant de la classe de base Exception) pour effectivement lever une exception.
<?php
function division($quantite, $nbParts)
    if (0 === $nbParts) throw new Exception('Impossible de diviser par 0');
    return $quantite/$nbParts;
}

6.8.3.5.La classe Exception

La classe Exception permet de véhiculer un message, un code et l'ensemble des informations nécessaires pour identifier le bout de code à l'origine de l'exception.
Elle propose ainsi les méthodes (pour ne citer que les principales):
  • getMessage()
  • getCode()
  • getTraceAsString()
Lors de l'instanciation d'une exception vous pouvez passer en premier paramètre une chaîne de caractères (i.e. un message) (comme dans l'exemple précédent) et en second paramètre un entier pour préciser un code d'erreur (que vous choisissez librement).
Ici vous pouvez apprendre :
Version imprimable: imprimer