Gestion des exceptions PHP

L'exception (Exception) est utilisée pour changer le flux normal du script lors de l'occurrence de certaines erreurs. Ce cas est appelé exception.

Qu'est-ce qu'une exception ?

PHP 5 offre une nouvelle méthode de gestion des erreurs orientée objet.

La gestion des exceptions est utilisée pour changer le flux normal du script lors de l'occurrence de certaines erreurs (exceptions). Ce cas est appelé exception.

Lorsque l'exception est déclenchée, cela se produit généralement :

  • L'état actuel du code est enregistré
  • L'exécution du code est basculée vers la fonction de gestion des exceptions prédéfinie
  • Selon la situation, le gestionnaire peut redémarrer l'exécution du code à partir de l'état de code enregistré, arrêter l'exécution du script ou continuer l'exécution du script à partir d'une autre position dans le code

Nous allons montrer différentes méthodes de gestion des erreurs :

  • Utilisation de base des exceptions
  • Créer un gestionnaire d'exception personnalisé
  • Exceptions multiples
  • Relancer l'exception
  • Définir un gestionnaire d'exception de niveau supérieur

Utilisation de base des exceptions

Lorsque l'exception est lancée, le code suivant ne continuera pas à s'exécuter, PHP essaiera de trouver un bloc de code "catch" correspondant.

Si l'exception n'est pas capturée et qu'aucun gestionnaire d'exception n'est utilisé avec set_exception_handler(), une erreur grave (erreur fatale) se produira et le message d'erreur "Uncaught Exception" (exception non capturée) sera affiché.

Essayons de lancer une exception sans la capturer :

<?php
//créer une fonction avec une exception
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("La valeur doit être 1 ou inférieure");
  }
 return true;
 }
//déclencher une exception
checkNum(2);
?>

Le code peut générer une erreur similaire :

Erreur fatale : Exception non attrapée 
avec le message 'La valeur doit être 1 ou inférieure' dans C:\webfolder\test.php:6 
Trace de pile : #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} lancé dans C:\webfolder\test.php en ligne 6

Try, throw et catch

Pour éviter les erreurs de l'exemple précédent, nous devons créer un code approprié pour gérer les exceptions.

Le gestionnaire correct doit inclure :

  1. Essayer - Les fonctions qui peuvent générer des exceptions doivent être placées dans un bloc de code "try". Si aucune exception n'est déclenchée, le code continuera normalement. Cependant, si une exception est déclenchée, une exception sera lancée.
  2. Throw - Ici, nous définissons comment déclencher une exception. Chaque "throw" doit correspondre à au moins un "catch"
  3. Catch - Le bloc de code "catch" capture l'exception et crée un objet contenant des informations sur l'exception

Lançons une exception :

<?php
//Créer une fonction qui peut lancer une exception
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("La valeur doit être 1 ou inférieure");
  }
 return true;
 }
//Déclencher l'exception dans le bloc de code "try"
try
 {
 checkNum(2);
 //Si l'exception est lancée, ce texte ne sera pas affiché
 echo 'Si vous voyez cela, le nombre est 1 ou inférieur';
 }
//Capture de l'exception
catch(Exception $e)
 {
 echo 'Message: ' .$e->getMessage();
 }
?>

Le code suivant génère un message d'erreur similaire :

Message: La valeur doit être 1 ou inférieure

Exemple d'explication :

Le code suivant lance une exception et la capture :

  1. Créer la fonction checkNum(). Elle vérifie si le nombre est supérieur à 1. Si c'est le cas, elle lance une exception.
  2. Appel de la fonction checkNum() dans le bloc de code "try".
  3. L'exception dans la fonction checkNum() est lancée
  4. Le bloc de code "catch" reçoit cette exception et crée un objet contenant des informations sur l'exception ($e).
  5. En appelant $e->getMessage() sur cet objet exception, vous pouvez afficher le message d'erreur de l'exception.

Cependant, pour suivre le principe de "chaque throw doit correspondre à un catch", vous pouvez configurer un gestionnaire d'exceptions de niveau supérieur pour traiter les erreurs manquantes.

Créer une classe Exception personnalisée

Créer un gestionnaire d'exception personnalisé est très simple. Nous avons simplement créé une classe spéciale, qui peut appeler ses fonctions lorsque survient une exception en PHP. Cette classe doit être une extension de la classe exception.

Cette classe exception personnalisée hérite de toutes les propriétés de la classe exception de PHP, vous pouvez y ajouter des fonctions personnalisées.

Nous allons commencer à créer la classe exception :

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //message d'erreur
  $errorMsg = 'Erreur à la ligne '.$this->getLine().' dans '.$this->getFile()
  : <b>'.$this->getMessage().'</b> n'est pas une adresse e-mail valide
  return $errorMsg;
  }
 }
$email = "someone@example...com";
try
 {
 //Vérifiez si 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //lancer une exception si l'e-mail n'est pas valide
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //affichage du message personnalisé
 echo $e->errorMessage();
 }
?>

Ce nouveau classe est une copie de l'ancienne classe d'exception, avec la fonction errorMessage(). Comme c'est une copie de l'ancienne classe, elle hérite des propriétés et des méthodes de l'ancienne classe, nous pouvons utiliser les méthodes de la classe Exception, comme getLine(), getFile() et getMessage().

Exemple d'explication :

Le code ci-dessus lance une exception et la capture via une classe d'exception personnalisée :

  1. La classe customException() est créée en tant qu'extension de l'ancienne classe exception. De cette manière, elle hérite de toutes les propriétés et méthodes de l'ancienne classe.
  2. Créez la fonction errorMessage(). Si l'adresse e-mail n'est pas valable, cette fonction renvoie un message d'erreur
  3. Définissez la variable $email comme une chaîne de caractères d'adresse e-mail non valable
  4. Exécutez le bloc "try", une exception est lancée en raison de l'adresse e-mail non valable
  5. Le bloc "catch" capture les exceptions et affiche le message d'erreur

Exceptions multiples

Vous pouvez utiliser plusieurs exceptions pour un segment de script pour détecter plusieurs cas.

Vous pouvez utiliser plusieurs blocs if..else ou un bloc switch, ou imbriquer plusieurs exceptions. Ces exceptions peuvent utiliser différentes classes d'exception et renvoyer différents messages d'erreur :

<?php
class customException extends Exception
{
public function errorMessage()
{
//message d'erreur
$errorMsg = 'Erreur à la ligne '.$this->getLine().' dans '.$this->getFile()
: <b>'.$this->getMessage().'</b> n'est pas une adresse e-mail valide
return $errorMsg;
}
}
$email = "someone@example.com";
try
 {
 //Vérifiez si 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //lancer une exception si l'e-mail n'est pas valide
  throw new customException($email);
  }
 //vérifier la présence de "example" dans l'adresse e-mail
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email est un e-mail exemple");
  }
 }
catch (customException $e)
 {
 echo $e->errorMessage();
 }
catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

Exemple d'explication :

Le code ci-dessus teste deux conditions, et si aucune des conditions n'est remplie, une exception est lancée :

  1. La classe customException() est créée en tant qu'extension de l'ancienne classe exception. De cette manière, elle hérite de toutes les propriétés et méthodes de l'ancienne classe.
  2. Création de la fonction errorMessage(). Si l'adresse e-mail n'est pas valable, cette fonction renvoie un message d'erreur.
  3. Exécutez le bloc "try", sous la première condition, aucune exception n'est lancée.
  4. En raison de la présence de la chaîne "example" dans l'e-mail, la deuxième condition déclenche l'exception.
  5. Le bloc "catch" capture les exceptions et affiche un message d'erreur approprié

Si l'exception customException n'est pas capturée, mais seulement l'exception de base, traitez l'exception là.

Relancer l'exception

Parfois, lorsque des exceptions sont lancées, vous pourriez souhaiter les traiter de manière différente de la norme. Vous pouvez relancer l'exception dans un bloc "catch".

Le script doit cacher les erreurs système aux utilisateurs. Les erreurs système peuvent être importantes pour les programmeurs, mais les utilisateurs n'y sont pas intéressés. Pour faciliter l'utilisation pour les utilisateurs, vous pouvez relancer une exception avec un message plus amical pour l'utilisateur :

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //message d'erreur
  $errorMsg = $this->getMessage().' est une adresse e-mail non valide.';
  return $errorMsg;
  }
 }
$email = "someone@example.com";
try
 {
 try
  {
  //vérifier la présence de "example" dans l'adresse e-mail
  if(strpos($email, "example") !== FALSE)
   {
   //lancer une exception si l'e-mail n'est pas valide
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //relancer l'exception
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //affichage du message personnalisé
 echo $e->errorMessage();
 }
?>

Exemple d'explication :

Le code ci-dessus détecte la présence de la chaîne "example" dans l'adresse e-mail. Si elle est présente, l'exception est relancée à nouveau :

  1. La classe customException() est créée en tant qu'extension de l'ancienne classe exception. De cette manière, elle hérite de toutes les propriétés et méthodes de l'ancienne classe.
  2. Création de la fonction errorMessage(). Si l'adresse e-mail n'est pas valable, cette fonction renvoie un message d'erreur.
  3. La variable $email est définie comme une adresse e-mail valide, mais contient la chaîne "example".
  4. Le bloc de code "try" contient un autre bloc "try", ce qui permet de relancer l'exception à nouveau.
  5. En raison de la présence de la chaîne "example" dans l'e-mail, l'exception est déclenchée.
  6. "catch" capture l'exception et relève à nouveau "customException".
  7. La capture de "customException" et l'affichage d'un message d'erreur.

Si une exception n'est pas capturée dans le bloc try actuel, elle cherchera un bloc catch à un niveau supérieur.

Définir un gestionnaire d'exception de niveau supérieur (Top Level Exception Handler)

La fonction set_exception_handler() peut définir une fonction utilisateur pour traiter toutes les exceptions non capturées.

<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Exception non capturée s'est produite');
?>

La sortie du code ci-dessus devrait être similaire à ce qui suit :

Exception : Exception non capturée s'est produite

Dans le code ci-dessus, il n'existe pas de bloc catch, mais un programme de gestion des exceptions de niveau supérieur est déclenché. Il est recommandé d'utiliser cette fonction pour capturer toutes les exceptions non capturées.

Règles des exceptions

  • Le code nécessitant la gestion des exceptions doit être placé à l'intérieur d'un bloc try, afin de capturer les exceptions potentielles.
  • Chaque bloc try ou throw doit au moins avoir un bloc catch correspondant.
  • L'utilisation de plusieurs blocs catch permet de capturer différents types d'exceptions.
  • Il est possible de relancer (re-thrown) une exception dans un bloc catch à l'intérieur d'un bloc try.

En un mot : si une exception est lancée, elle doit être capturée.