Définition et gestion des erreurs en PHP

Dans cette nouvelle leçon, nous allons définir ce qu’est une erreur en PHP et comprendre comment les erreurs sont générées par le PHP ainsi que comment créer un gestionnaire d’erreurs personnalisé.

 

Qu’est-ce qu’une erreur en PHP ?

Tout code peut rencontrer une situation anormale qui va l’empêcher de s’exécuter correctement.

Ces « situations anormales » peuvent parfois provenir du code lui-même, c’est-à-dire d’erreurs faites par les développeurs qui l’ont écrit comme par exemple l’utilisation d’une variable non définie ou le passage d’arguments incorrects dans une fonction ou encore l’oubli d’une parenthèse ou d’un point-virgule quelque part dans le code.

Parfois, également, un code ne va pas pouvoir s’exécuter correctement à cause d’un problème externe comme par exemple dans le cas où on souhaite inclure un fichier dans un script mais que le fichier en question ne peut pas être inclus pour le moment pour diverses raisons.

Dans ces cas-là, le PHP va signaler les problèmes rencontrés lors de l’exécution du code en renvoyant ce qu’on appelle une erreur. A chaque fois que HP génère une erreur, il inclut également un type qui prend la forme d’une constante. Selon le problème rencontré, le niveau ou « type » d’erreur renvoyé sera différent et selon le type d’erreur le script pourra continuer à s’exécuter normalement ou au contraire sera stoppé brutalement.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php
            //La variable $x n'a pas été définie
            echo $x;
            
            //Le fichier jenexistepas.php n'existe pas
            include 'jenexistepas.php';
            
            echo '<br>Ceci s\'affiche car simples warning renvoyé au dessus<br>';
            
            //Le fichier jenexistepas.php n'existe pas
            require 'jenexistepas.php';
            
            echo 'Ceci ne s\'affichera pas car erreur fatale ci-dessus';
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

Présentation des différents types d'erreurs PHP

Dans l’exemple ci-dessus, je commence par essayer d’echo une variable $x non définis. Comme PHP n’arrive pas à trouver la variable, il renvoie une erreur de type E_NOTICE.

Ensuite, je tente d’inclure un fichier qui n’existe pas avec include. PHP renvoie deux erreurs mais de type E_WARNING indiquant que la ressource n’a pas été trouvée et qu’elle n’a pas pu être ouverte (dans certains cas, le fichier sera trouvé mais ne pourra pas être ouvert pour telle ou telle raison).

Finalement, je tente à nouveau d’inclure un fichier qui n’existe pas mais en utilisant cette fois-ci require qui est plus stricte que include. Cette fois-ci, le PHP va renvoyer une erreur de type E_WARNING pour indiquer que le fichier n’a pas été trouvé et une deuxième de type E_ERROR (erreur fatale) qui va stopper l’exécution du script.

 

La gestion des erreurs par le PHP et les types d’erreurs

Il existe 16 niveaux ou types d’erreurs différentes en PHP. Chaque type d’erreur possède une constante et une valeur associées et le script va se comporter différemment en fonction de l’erreur rencontrée.

Ces erreurs peuvent être rangées en différents groupes : les erreurs du code classiques (erreur du développeur), les erreurs liées au code source de PHP, les erreurs générées par le moteur Zend (le moteur ou « framework » sur lequel PHP se base) et les erreurs générées par l’utilisateur.

Vous pouvez trouver ci-dessous la liste des différentes constantes d’erreurs, des valeurs associées et une description de chaque type d’erreur :

ValeurConstanteDescription
1E_ERRORErreur fatale qui va être affichée par défaut. Ce sont des erreurs qui ne peuvent pas être ignorées. L’exécution du script est interrompue.
2E_WARNINGAlerte qui va être affichée par défaut. Elles indiquent un problème qui doit être intercepté par le script durant l’exécution du script. L’exécution du script n’est pas interrompue.
4E_PARSELes erreurs d’analyse ne doivent être générées que par l’analyseur. Vous n’aurez donc pas à vous en préoccuper.
8E_NOTICELes notices ou « remarques » ne sont pas affichées par défaut, et indiquent que le script a rencontré quelque chose qui peut être une erreur, mais peut aussi être un événement normal dans la vie du script (ex : essayer d’accéder à une valeur non déclarée)
16E_CORE_ERRORComparable à E_ERROR mais générée par le code source de PHP. Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
32E_CORE_WARNINGComparable à E_WARNING mais générée par le code source de PHP. Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
64E_COMPILE_ERRORComparable à E_ERROR mais générée par le moteur Zend. Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
128E_COMPILE_WARNINGComparable à E_WARNING mais générée par le moteur Zend. Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
256E_USER_ERRORMessage d’erreur généré par l’utilisateur. Comparable à E_ERROR. Elle est générée par le programmeur en PHP par l’utilisation de la fonction trigger_error(). Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
512E_USER_WARNINGMessage d’erreur généré par l’utilisateur. Comparable à E_WARNING. Elle est générée par le programmeur en PHP par l’utilisation de la fonction trigger_error(). Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
1024E_USER_NOTICEMessage d’erreur généré par l’utilisateur. Comparable à E_NOTICE. Elle est générée par le programmeur en PHP par l’utilisation de la fonction trigger_error(). Les fonctions de PHP ne doivent pas générer ce genre d’erreur.
2048E_STRICTPermet d’obtenir des suggestions de PHP pour modifier notre code, assurant ainsi une meilleure interopérabilité et compatibilité de celui-ci
4096E_RECOVERABLE_ERRORErreur fatale qui peut être captée. Ceci indique qu’une erreur probablement dangereuse s’est produite, mais n’a pas laissé le moteur Zend dans un état instable. Si on ne capture pas l’erreur, le script est stoppé comme pour une erreur E_ERROR
8192E_DEPRECATEDAlertes d’exécution. On va activer cette option pour recevoir des alertes sur les portions de code qui pourraient ne pas fonctionner avec les futures versions
16384E_USER_DEPRECATEDMessage d’alerte généré par l’utilisateur. Fonctionne de la même façon que E_DEPRECATED, mise à part que le message est généré par notre code PHP en utilisant la fonction trigger_error()
32767E_ALLToutes les erreurs et alertes supportées

Si aucun gestionnaire d’erreur n’est défini, PHP gèrera les erreurs qui se produisent en fonction de sa configuration. La directive error_reporting du fichier php.ini (le fichier de configuration principal de PHP) va définir quelles erreurs vont être rapportées et quelles erreurs vont être ignorées.

Notez qu’on va tout à fait pouvoir définir quelles erreurs doivent être rapportées et quelles erreurs doivent être ignorées en modifiant manuellement cette directive. Dans la plupart des cas, il sera préférable de tout rapporter par défaut en utilisant la valeur E_ALL.

Ensuite, l’affichage ou le non affichage des erreurs rapportées va être défini par une autre directive du fichier php.ini qui est la directive display_errors. Si vous ne voyez pas les erreurs comme moi, il vous faudra probablement modifier la valeur de cette directive.

 

Créer des gestionnaires d’erreurs personnalisés

Parfois, la prise en charge d’une erreur par défaut par le PHP ne va nous convenir. Dans ce cas-là, on voudra créer un gestionnaire personnalisé d’erreurs.

Pour réaliser cela, on va pouvoir utiliser la fonction set_error_handler() à laquelle on va passer une fonction de rappel qui sera notre gestionnaire d’erreurs.

Notez qu’on va également pouvoir passer en deuxième argument de set_error_handler() une constante d’erreur qui va définir le type d’erreurs pour lequel notre fonction gestionnaire d’erreurs doit être appelée. Si on ne précise rien, le gestionnaire sera appelé pour toutes les erreurs.

Notez également qu’on ne va pas pouvoir gérer tous les types d’erreurs de cette façon. En particulier, les types d’erreur E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING ainsi que la plupart des E_STRICT du fichier dans lequel set_error_handler() est appelée ne pourront pas être gérés de cette façon.

Le but de la fonction de rappel créée va être de récupérer les différentes informations renvoyées par le PHP en cas d’erreur et de les utiliser pour effectuer différentes opérations. Pour cela, on va pouvoir définir entre 2 et 4 paramètres pour notre fonction :

  • Le premier paramètre va représenter le niveau d’erreur ;
  • Le deuxième paramètre représente le message d’erreur renvoyé par le PHP ;
  • Le troisième paramètre (optionnel) représente le nom du fichier dans lequel l’erreur a été identifiée ;
  • Le quatrième paramètre (optionnel) représente le numéro de ligne à laquelle l’erreur a été identifiée.

Le PHP va lui-même transmettre les valeurs en arguments de notre fonction en cas d’erreur. Regardez plutôt l’exemple ci-dessous :

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php
            $x = 5;
            $y = 0;
            
            set_error_handler(function($niveau, $message, $fichier, $ligne){
                echo 'Erreur : ' .$message. '<br>';
                echo 'Niveau de l\'erreur : ' .$niveau. '<br>';
                echo 'Erreur dans le fichier : ' .$fichier. '<br>';
                echo 'Emplacement de l\'erreur : ' .$ligne. '<br>';
            });
            
            echo $x / $y;
            echo '<br><br>';
            echo $z;
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

Création d'un gestionnaire d'erreurs PHP

On utilise ici une fonction anonyme comme fonction de rappel de set_error_handler() et donc comme gestionnaire d’erreurs. On définit 4 paramètres pour cette fonction.

Dans le cas présent, la fonction va se contenter d’echo les différentes informations liées à l’erreur de façon structurée et elle n’est donc pas très utile en l’état. Cependant, on va également pouvoir définir des fonctions bien plus complexes qui vont effectuer telle ou telle action en fonction des valeurs reçues (par exemple « si l’erreur est de telle niveau alors exécute ceci…).

Deux erreurs sont générées ici : mathématiquement parlant, la division par zéro est une aberration (le résultat va tendre vers l’infini d’où le « INF » de renvoyé) et une première erreur est donc renvoyée. Ensuite, on tente d’echo une variable qui n’a pas été définie et une deuxième erreur est donc renvoyée.

Laisser un commentaire