IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Exceptions et PHP5


précédentsommairesuivant

I. Présentation

Les exceptions sont pour beaucoup de personnes un système élaboré de gestion d'erreurs. Ce n'est pas le cas. Et même si dans la pratique, on peut, comme nous le verrons, établir des liens entre ces deux concepts, leurs buts sont totalement différents. Une erreur est dans la majorité des cas assimilable à un bug, c'est-à-dire une réaction non désirée. Une exception est un traitement qui sera appelé lorsqu'un cas particulier est détecté pendant le déroulement du programme.
Pour synthétiser, une erreur est le résultat un fonctionnement anormal alors qu'une exception est un fonctionnement normal, mais exceptionnel.

I-A. Mots-clés [throw] [try] [catch]

Comme tous les mots-clés de programmation, ces trois mots proviennent de l'anglais et signifient

  • throw : lancer ;
  • try : essayer ;
  • catch : attraper.

La signification de ces trois mots-clés est très représentative du mécanisme utilisé et doit toujours être gardée à l'esprit. En effet, les exceptions fonctionnent de la même façon dans tous les langages. Dans un bloc défini (try), l'environnement d'exécution envoie un signal (throw) au gestionnaire d'exceptions qui diffusera l'information aux différents blocs de traitement (catch). Le bloc adéquat au signal émis attrapera alors le signal (catch) et exécutera un code adapté.

La mise en place d'une exception se présente comme ceci :

Mécanisme simple d'exception
Sélectionnez
try 
{ 
    throw new Exception ('ceci est faux'); 
    echo 'Code non exécuté';
} 
catch(Exception $myException) 
{ 
    echo $myException->getMessage(); 
}

Le déroulement de ce code est le suivant :

  1. On entre dans le bloc try ;
  2. On lance une exception (on dit aussi « soulever une exception ») ;
  3. On quitte le bloc try (sans exécuter le code restant du bloc try) ;
  4. Le catch attrape l'exception ;
  5. On exécute le contenu du bloc catch.

Le code précédent affichera ainsi :

Affichage
Sélectionnez
Ceci est faux

Il s'agit ici du cas le plus simple, car l'exception est au même niveau que le bloc try/catch et nous n'avons traité qu'un cas d'exception, en utilisant la classe native de PHP. Nous allons voir qu'il est possible de personnaliser ce mécanisme par l'écriture de classe d'exception propre à un contexte, et comment utiliser au mieux ce mécanisme, en comprenant bien le rôle et la place du throw et des blocs try/catch

I-B. Profondeur de throw

Un bloc try peut ne pas contenir directement de throw. Les throw sont en effet répartis dans le code en fonction des besoins. On peut ainsi lancer une exception dans une fonction, et placer l'appel à cette fonction dans un bloc try.

Utilisation des exceptions dans une fonction
Sélectionnez
function verif_text( $text ) 
{ 
    if (empty($text)) 
    { 
        throw new Exception ('Le texte est vide'); 
    } 
    else 
    { 
        return $text; 
    } 
}
 
 
try 
{ 
    verif_text( '' ); 
} 
catch(Exception $myException) 
{ 
    echo $myException->getMessage(); 
}

Cet exemple lancera bien l'exception et affichera le message 'Le texte est vide'.
Le principe est exactement le même dans les méthodes d'une classe.
On a vu au I-A que le code suivant un throw dans un bloc try n'était pas exécuté. Il en est de même ici, même à l'intérieur de la fonction. Ainsi, ceci :

Exemple d'interruption de fonction par une exception
Sélectionnez
function myFct()
{
    throw new Exception("Voici l'exception");
    echo "Une exception vient d'être levée";
}
 
 
try
{
    myFct();
}
catch(Exception $e)
{
    echo $e->getMessage();
}

affichera uniquement

Affichage
Sélectionnez
Voici l'exception

Il est donc inutile de mettre un die, exit ou return directement après un throw, la fonction est de toute manière interrompue.

L'intérêt est de distinguer les instructions throw et try/catch. L'écriture d'une classe ou d'une fonction ne devrait contenir que des throw, et rarement de try/catch que l'on utilise plus lors des appels de ces classes/fonctions.

I-C. Intérêt des exceptions

L'intérêt des exceptions par rapport aux erreurs est multiple

  • Pouvoir interrompre un bloc de code si on détecte la moindre exception.
  • Pouvoir générer des exceptions pour les erreurs système, mais aussi pour les erreurs utilisateur ou tout autre évènement défini par le développeur.
  • Personnaliser le traitement de l'exception dans le bloc catch et ainsi appliquer un correctif ou une alerte adaptée.

On pourrait alors se dire que les exceptions ne sont qu'un système d'erreurs évolué. Pas du tout ! Il faut bien distinguer les erreurs des exceptions. Une erreur est en général une réponse du système à un problème rencontré. Les exceptions sont des alertes dont l'emplacement et le comportement sont définis par le développeur. Les exceptions permettent de gérer les erreurs, la réciproque n'a pas de sens.

Les exceptions répondent à un besoin, qui est de laisser la gestion des erreurs utilisateur aux mécanismes adaptés pour ceci. Vous pensez que c'est ce que vous faites ? Qui n'a jamais écrit une fonction de ce type ?

Exemple de fonction renvoyant valeur et erreur
Sélectionnez
<?php 
function testLogin( $login ) 
{ 
    if ( ! ($res = mysql_query("SELECT 1 FROM membres WHERE login='".mysql_real_escape_string($login)."'")) ) 
    { 
        return FALSE; 
    } 
    else 
    { 
        $row = mysql_fetch_assoc($res); 
        if ($row['login'] == $login) 
        { 
            return TRUE; 
        } 
        else 
        { 
            return FALSE; 
        } 
    } 
} 
?>

Ceci est une horreur. Que peut-on conclure si la fonction retourne un false ? Absolument rien, peut-être y a-t-il eu une erreur, peut-être pas…

Par définition, une fonction doit toujours renvoyer une valeur attendue et jamais une erreur (et encore moins les deux en même temps). Imaginez votre voiture, vous mettez de l'essence en entrée, vous obtenez une vitesse en sortie. Lorsqu'un problème intervient, avec le système incorrect ci-dessus, vous obtiendrez que votre vitesse soit nulle, la voiture ne fonctionne plus, et c'est tout. Or, le problème en question n'est qu'un feu-stop cassé. Avec les exceptions, la voiture continue de rouler, vous lisez la vitesse sur le compteur, et un petit voyant s'est allumé sur le tableau de bord indiquant qu'un feu-stop est cassé.

En renvoyant erreurs et valeurs, des collisions peuvent se produire, car false == 0.

Il faudra donc typer les comparaisons pour distinguer les erreurs des valeurs.

Par exemple :

if ( countMembre() === false ) { // c'est une erreur…

if ( countMembre() === 0) { // Il y a 0 membre…


précédentsommairesuivant

Copyright © 13/09/2006 Guillaume Affringue. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.