PHP Gestion des Exceptions
Les exceptions sont utilisées pour modifier le flux normal d'un script lorsqu'une erreur spécifiée se produit.
Qu'est-ce qu'une Exception
Avec PHP 5, une nouvelle façon orientée objet de gérer les erreurs a été introduite.
La gestion des exceptions permet de modifier le flux normal de l'exécution du code si une condition d'erreur (exceptionnelle) spécifiée se produit. Cette condition est appelée une exception.
Voici ce qui se passe normalement lorsqu'une exception est déclenchée :
- L'état actuel du code est sauvegardé
- L'exécution du code passe à une fonction de gestionnaire d'exception prédéfinie (personnalisée)
- Selon la situation, le gestionnaire peut alors reprendre l'exécution à partir de l'état de code sauvegardé, terminer l'exécution du script ou continuer le script à partir d'un autre emplacement dans le code
Nous allons montrer différentes méthodes de gestion des erreurs :
- Utilisation de base des Exceptions
- Création d'un gestionnaire d'exception personnalisé
- Exceptions multiples
- Relancer une exception
- Définir un gestionnaire d'exception de niveau supérieur
Remarque : Les exceptions ne doivent être utilisées qu'en cas de conditions d'erreur et ne doivent pas être utilisées pour sauter à un autre endroit dans le code à un moment donné.
Utilisation de Base des Exceptions
Lorsqu'une exception est lancée, le code qui suit ne sera pas exécuté, et PHP essaiera de trouver le bloc "catch" correspondant.
Si une exception n'est pas interceptée, une erreur fatale sera émise avec un message "Exception non interceptée".
Essayons de lancer une exception sans l'intercepter :
<?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 ci-dessus générera une erreur comme ceci :
Erreur fatale : Exception non interceptée 'Exception'
avec le message 'La valeur doit être 1 ou inférieure' dans C:\webfolder\test.php:6
Trace de la pile : #0 C:\webfolder\test.php(12):
checkNum(28) #1 {main} lancé dans C:\webfolder\test.php à la ligne 6 Essayer, lancer et attraper
Pour éviter l'erreur de l'exemple ci-dessus, nous devons créer le code approprié pour gérer une exception.
Un code d'exception approprié doit inclure :
-
try- Une fonction utilisant une exception doit être dans un bloc "try". Si l'exception ne se déclenche pas, le code continuera normalement. Cependant, si l'exception se déclenche, une exception est "lancée" -
throw- C'est ainsi que vous déclenchez une exception. Chaque "throw" doit avoir au moins un "catch" -
catch- Un bloc "catch" récupère une exception et crée un objet contenant les informations de l'exception
Essayons de déclencher une exception avec un code valide :
<?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 dans un bloc "try"
try {
checkNum(2);
//Si l'exception est lancée, ce texte ne sera pas affiché
echo 'Si vous voyez ceci, le nombre est 1 ou inférieur';
}
//attraper l'exception
catch(Exception $e) {
echo 'Message : ' .$e->getMessage();
}
?> Le code ci-dessus générera une erreur comme ceci :
Message : La valeur doit être 1 ou inférieure Exemple expliqué :
Le code ci-dessus lance une exception et l'attrape :
- La fonction checkNum() est créée. Elle vérifie si un nombre est supérieur à 1. Si c'est le cas, une exception est lancée
- La fonction checkNum() est appelée dans un bloc "try"
- L'exception dans la fonction checkNum() est lancée
- Le bloc "catch" récupère l'exception et crée un objet ($e) contenant les informations de l'exception
- Le message d'erreur de l'exception est affiché en appelant $e->getMessage() depuis l'objet d'exception
Cependant, une façon de contourner la règle "chaque throw doit avoir un catch" est de définir un gestionnaire d'exception de niveau supérieur pour gérer les erreurs qui échappent.
Création d'une Classe d'Exception Personnalisée
Pour créer un gestionnaire d'exception personnalisé, vous devez créer une classe spéciale avec des fonctions qui peuvent être appelées lorsqu'une exception se produit en PHP. La classe doit être une extension de la classe d'exception.
La classe d'exception personnalisée hérite des propriétés de la classe d'exception de PHP et vous pouvez y ajouter des fonctions personnalisées.
Créons une classe d'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érifier si
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//lancer une exception si l'email n'est pas valide
throw new customException($email);
}
}
catch (customException $e) {
//afficher le message personnalisé
echo $e->errorMessage();
}
?> La nouvelle classe est une copie de l'ancienne classe d'exception avec l'ajout de la fonction errorMessage(). Puisqu'il s'agit d'une copie de l'ancienne classe, et qu'elle hérite des propriétés et méthodes de l'ancienne classe, nous pouvons utiliser les méthodes de la classe d'exception comme getLine(), getFile() et getMessage().
Exemple expliqué :
Le code ci-dessus lance une exception et l'attrape avec une classe d'exception personnalisée :
- La classe customException() est créée comme une extension de l'ancienne classe d'exception. De cette manière, elle hérite de toutes les méthodes et propriétés de l'ancienne classe d'exception
- La fonction errorMessage() est créée. Cette fonction retourne un message d'erreur si une adresse e-mail est invalide
- La variable $email est définie sur une chaîne qui n'est pas une adresse e-mail valide
- Le bloc "try" est exécuté et une exception est lancée puisque l'adresse e-mail est invalide
- Le bloc "catch" attrape l'exception et affiche le message d'erreur
Exceptions Multiples
Il est possible pour un script d'utiliser plusieurs exceptions pour vérifier plusieurs conditions.
Il est possible d'utiliser plusieurs blocs if..else, un switch, ou d'imbriquer plusieurs exceptions. Ces exceptions peuvent utiliser différentes classes d'exception et retourner 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érifier si
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
//lancer une exception si l'email n'est pas valide
throw new customException($email);
}
//vérifier "example" dans l'adresse mail
if(strpos($email, "example") !== FALSE) {
throw new Exception("$email est un e-mail d'exemple");
}
}
catch (customException $e) {
echo $e->errorMessage();
}
catch(Exception $e) {
echo $e->getMessage();
}
?> Exemple expliqué :
Le code ci-dessus teste deux conditions et lance une exception si l'une des conditions n'est pas remplie :
- La classe customException() est créée comme une extension de l'ancienne classe d'exception. De cette manière, elle hérite de toutes les méthodes et propriétés de l'ancienne classe d'exception
- La fonction errorMessage() est créée. Cette fonction retourne un message d'erreur si une adresse e-mail est invalide
- La variable $email est définie sur une chaîne qui est une adresse e-mail valide, mais contient la chaîne "example"
- Le bloc "try" est exécuté et une exception n'est pas lancée sur la première condition
- La deuxième condition déclenche une exception puisque l'e-mail contient la chaîne "example"
- Le bloc "catch" attrape l'exception et affiche le message d'erreur correct
Si l'exception lancée était de la classe customException et qu'il n'y avait pas de catch pour customException, seulement le catch de base, l'exception serait gérée là.
Relancer des Exceptions
Parfois, lorsqu'une exception est lancée, vous pouvez souhaiter la gérer différemment de la manière standard. Il est possible de relancer une exception une seconde fois dans un bloc "catch".
Un script doit cacher les erreurs système aux utilisateurs. Les erreurs système peuvent être importantes pour le codeur, mais ne présentent aucun intérêt pour l'utilisateur. Pour faciliter les choses pour l'utilisateur, vous pouvez relancer l'exception avec un message convivial :
<?php
class customException extends Exception {
public function errorMessage() {
//message d'erreur
$errorMsg = $this->getMessage().' n\'est pas une adresse e-mail valide.';
return $errorMsg;
}
}
$email = "someone@example.com";
try {
try {
//vérifier "example" dans l'adresse mail
if(strpos($email, "example") !== FALSE) {
//lancer une exception si l'email n'est pas valide
throw new Exception($email);
}
}
catch(Exception $e) {
//relancer l'exception
throw new customException($email);
}
}
catch (customException $e) {
//afficher le message personnalisé
echo $e->errorMessage();
}
?> Exemple expliqué :
Le code ci-dessus teste si l'adresse e-mail contient la chaîne "example", si c'est le cas, l'exception est relancée :
- La classe customException() est créée comme une extension de l'ancienne classe d'exception. De cette manière, elle hérite de toutes les méthodes et propriétés de l'ancienne classe d'exception
- La fonction errorMessage() est créée. Cette fonction retourne un message d'erreur si une adresse e-mail est invalide
- La variable $email est définie sur une chaîne qui est une adresse e-mail valide, mais contient la chaîne "example"
- Le bloc "try" contient un autre bloc "try" pour permettre de relancer l'exception
- L'exception est déclenchée puisque l'e-mail contient la chaîne "example"
- Le bloc "catch" attrape l'exception et relance une "customException"
- La "customException" est attrapée et affiche un message d'erreur
Si l'exception n'est pas interceptée dans son bloc "try" actuel, elle recherchera un bloc catch à des "niveaux supérieurs".
Définir un Gestionnaire d'Exception de Niveau Supérieur
La fonction set_exception_handler() définit une fonction définie par l'utilisateur pour gérer toutes les exceptions non interceptées :
<?php
function myException($exception) {
echo "<b>Exception:</b> " . $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Une exception non interceptée s\'est produite');
?> La sortie du code ci-dessus devrait être quelque chose comme ceci :
Exception : Une exception non interceptée s'est produite Dans le code ci-dessus, il n'y avait pas de bloc "catch". Au lieu de cela, le gestionnaire d'exception de niveau supérieur a été déclenché. Cette fonction doit être utilisée pour attraper les exceptions non interceptées.
Règles pour les exceptions
- Le code peut être entouré d'un bloc try pour aider à attraper les exceptions potentielles
- Chaque bloc try ou "throw" doit avoir au moins un bloc catch correspondant
- Plusieurs blocs catch peuvent être utilisés pour attraper différentes classes d'exceptions
- Les exceptions peuvent être lancées (ou relancées) dans un bloc catch au sein d'un bloc try
Une règle simple : Si vous lancez quelque chose, vous devez l'attraper.