Developpez.com - PHP
X

Choisissez d'abord la catégorieensuite la rubrique :


Politiques de gestion des erreurs en PHP

Date de mise à jour : 29/10/06 (version 0.22)

Par Guillaume Piolle (Page perso sur DVP)
 

Ce cours traite des erreurs PHP, des différents outils qu'offre le langage pour les gérer, des bonnes pratiques de développement et le déploiement d'applications web en termes d'erreurs PHP. Les exceptions ne sont pas traitées dans ce tutoriel, mais dans l'article intitulé Exceptions et PHP5.

               Version PDF (Miroir)   Version hors-ligne (Miroir)

I. Introduction
II. Présentation des erreurs PHP
III. Les outils à notre disposition
III-A. Configuration du niveau d'erreur
III-B. Génération d'erreurs
III-C. Masquage des erreurs
III-D. Journalisation
III-E. Le remote debugging
III-F. Personnalisations diverses
III-G. Interception
IV. Les assertions
V. Les principes d'une politique efficace
IV-A. Phase de développement
IV-B. Phase de production
VI. Implémentation
V-A. Via le fichier de configuration php.ini
V-B. Via une classe PHP
VII. Remerciements
VIII. Références


I. Introduction

Comme tous les langages de programmation, PHP est susceptible de générer, d'afficher et de traiter des erreurs. Le terme étant à dénotation intrinsèquement négative, on a forcément tendance à vouloir les éviter à tout prix, à obtenir une exécution sans aucun message d'erreur, quitte à les ignorer, ce qui revient à entasser la poussière sous le tapis du salon lorsqu'on fait le ménage... En réalité il vaudrait sans doute mieux considérer les mécanismes d'erreurs comme des aides à la programmation. Certes c'est toujours désagréable de récolter une série de messages d'erreurs lorsqu'on vient de finir de coder l'application qui révolutionnera l'avenir de l'internet ! Mais les erreurs PHP permettent de corriger les défauts de l'application, d'améliorer son style de programmation, et de gérer les impondérables qui surviendront lorsque des utilisateurs réels expérimenteront l'application.

Messages d'erreurs PHP standard
Messages d'erreurs PHP standard
Quels sont donc les enjeux d'une politique de gestion des erreurs ? Tout d'abord et évidemment, il faudra utiliser intelligemment ces erreurs en phase de développement et surtout de tests. Ensuite, il faudra prendre garde à ce que ces messages d'erreurs ne viennent pas défigurer une charte graphique soignée lorsqu'on mettra l'application en production : on prendra alors soin de masquer les erreurs aux visiteurs, tout en gardant la possibilité d'en être averti (phase de maintenance de l'application).


II. Présentation des erreurs PHP

En programmation, une erreur est définie comme un comportement anormal de l'application. En PHP on les distingue des exceptions, qui sont des comportements exceptionnels, mais cependant normaux. Dans certains cas, vous serez amenés à vous demander si c'est une erreur que vous devez définir, ou une exception. Tout est une question de sémantique, mais aussi d'outils associés. Le comportement de PHP n'est pas le même face à une erreur et face à une exception (et les deux sont configurables). La gestion des exceptions en PHP5 est décrite dans fr cet article.

Dans un langage de programmation compilé, comme le C, on distingue les erreurs de compilation des erreurs d'exécution. Les erreurs de compilation sont celles qui peuvent être anticipées par la machine dès l'écriture du code, et qui empêchent la génération du langage machine. Ce sont les plus facile à corriger puisque le compilateur (le préprocesseur, l'analyseur syntaxique, l'éditeur de liens...) donne une liste de ces erreurs à chaque tentative de compilation. Les erreurs d'exécution sont plus sournoises, ce sont ces "segmentation faults" qui n'apparaissent que lorsque le programme (mal testé ?) est en production et que l'utilisateur entre des valeurs bizarres dans la machine. PHP, lui, est un langage interprété, donc cette distinction n'existe pas vraiment : toutes les erreurs apparaîtront dans la phase d'interprétation du script. Néanmoins il reste certaines similitudes. Par exemple dans un compilateur comme dans un interpréteur, il y a un analyseur syntaxique qui va vérifier que votre programme est bien conforme à la grammaire formelle du langage (c'est-à-dire que vous avez respecté la syntaxe, que vous n'avez pas oublié un point-virgule dans un coin, ce genre de choses). Les erreurs rencontrées par cette analyseur syntaxique sont les "parse errors" (erreurs d'analyse), les erreurs que vous verrez sans doute apparaître en premier puisqu'elles empêchent l'interprétation du reste du script.

En fait toutes les erreurs PHP sont réparties en catégories, soit par nature, soit par gravité de l'erreur (gravité qui peut être subjective ou dépendante de l'application, d'ailleurs). Voici un petit tableau récapitulatif :

Valeur décimale Valeur hexadécimale Valeur binaire Constante PHP Affichage Apache Description
1 0001 00000000 00000001 E_ERROR Fatal error Le niveau d'erreur "standard". Par défaut, ces erreurs sont affichées par l'interpréteur, et l'exécution du script est stoppée. Elles sont donc destinées à désigner des erreurs suffisamment graves pour interrompre l'affichage de la page. C'est ce type d'erreur qui sera levée si vous appelez une fonction qui n'existe pas, par exemple.
2 0002 00000000 00000010 E_WARNING Warning Les warnings, ou "alertes", sont affichées mais n'arrêtent pas l'exécution, par analogie avec les langages compilés, où ils ne stoppent pas la compilation. C'est une erreur de moindre gravité, qui permet tout de même au reste du script de s'exécuter (comme la division par zéro dans l'exemple d'exécution affiché plus haut).
4 0004 00000000 00000100 E_PARSE Parse error La faute de syntaxe, l'erreur "énervante", celle que l'on garde pour soi et dont on ne fait pas profiter les copains ou les forums d'aide, parce qu'on a bien trop honte... Cette erreur n'apparaît qu'à l'étape de codage, et elle signifie que l'interpréteur n'a même pas été lancé sur votre code, parce que l'analyseur syntaxique a détecté un problème : votre code ne respecte pas la syntaxe PHP. Vous avez oublié de fermer une parenthèse ou une accolade par exemple, ou bien vous avez oublié un point-virgule.
8 0008 00000000 00001000 E_NOTICE Notice Les "notifications" sont à peine des erreurs, ce sont des indications de l'interpréteur, qui peuvent le plus souvent être ignorées (d'ailleurs par défaut elles ne sont même pas affichées), mais qui pourtant peuvent avoir beaucoup d'intérêt pour identifier les bogues. C'est le genre d'erreur qui apparaît par exemple lorsque vous utilisez une variable ou une constante non encore déclarée, ce que pourtant vous faites tout le temps, j'en suis sûr !
16 0010 00000000 00010000 E_CORE_ERROR   Ce type d'erreur est générée par le code de l'interpréteur PHP, et ne concerne pas le développeur. Vous n'en entendrez probablement jamais parler.
32 0020 00000000 00100000 E_CORE_WARNING   Ce type d'erreur est générée par le code de l'interpréteur PHP, et ne concerne pas le développeur. Vous n'en entendrez probablement jamais parler.
64 0040 00000000 01000000 E_COMPILE_ERROR   Ce type d'erreur est générée par le Zend Scripting Engine, et ne concerne pas le développeur. Vous n'en entendrez probablement jamais parler.
128 0080 00000000 10000000 E_COMPILE_WARNING   Ce type d'erreur est générée par le Zend Scripting Engine, et ne concerne pas le développeur. Vous n'en entendrez probablement jamais parler.
256 0100 00000001 00000000 E_USER_ERROR   C'est une erreur similaire à E_ERROR, mais générée directement par l'utilisateur via trigger_error (voir plus tard).
512 0200 00000010 00000000 E_USER_WARNING   C'est un avertissement similaire à E_WARNING, mais généré directement par l'utilisateur via trigger_error (voir plus tard).
1024 0400 00000100 00000000 E_USER_NOTICE   C'est une notification similaire à E_NOTICE, mais générée directement par l'utilisateur via trigger_error (voir plus tard).
2048 0800 00001000 00000000 E_STRICT   Uniquement à partir de PHP 5(1). Ces erreurs sont des notifications (donc pas vraiment graves) destinées à améliorer votre code pour le rendre compatible avec certaines recommandations officielles de PHP. Si vous ne les respectez pas, comme pour les notifications, votre programme peut fonctionner quand même. Mais si vous les respectez, il aura d'autant plus de chances de s'exécuter sans erreur sur une autre machine ou une nouvelle configuration !
4096 1000 00010000 00000000 E_RECOVERABLE_ERROR   Uniquement à partir de PHP 5(2). C'est une erreur relativement grave venant de la machine Zend. Ce n'est vraiment pas une erreur courante, et pour être tout à fait honnête je ne sais rien à son sujet. Vous ne devriez jamais la rencontrer, sauf à aller fouiner dans l'interpréteur, auquel cas vous savez sans doute mieux que moi ce que vous faites !
8191 1FFF 00011111 11111111 E_ALL   Dans les versions de PHP < 5(3), la valeur numérique est en fait 2047, et 6143 en PHP 5, ce qui correspond dans les deux cas à la somme de tous les codes d'erreur valides, à l'exception de E_STRICT. C'est donc un code qui permet d'embrasser toutes ces catégories. A partir de PHP 6.0, cette valeur sera "enfin" de 8191, ce qui correspond vraiment à la totalité des erreurs.
Le codage bit à bit de tous les codes d'erreurs, qui ne choquera On remarquera en particulier que la valeur E_ALL ne couvre pas les erreurs E_STRICT.

Niveaux d'erreur, informations associées (message, script, numéro de ligne)

Valeurs de retour à NULL ou FALSE, or, or die (à éviter)


III. Les outils à notre disposition


III-A. Configuration du niveau d'erreur

configuration du niveau d'erreur (php.ini et en ligne) php.ini : error_reporting = ... un mot sur E_ALL et E_STRICT


III-B. Génération d'erreurs

Avec trigger_error E_USER_NOTICE E_USER_WARNING E_USER_ERROR


III-C. Masquage des erreurs

Désactivation des erreurs avec @, à éviter php.ini : display_errors = Off


III-D. Journalisation

php.ini : log_errors = On, error_log = fichier Attention à la journalisation vue comme une poubellisation ignore_repeated_errors error_log = syslog : journalisation système (sur un système dédié) log manuel avec error_log($message) envoi par mail avec error_log($message, 1, $email, $headers); titre du message non modifiable car header Subject déjà existant utile en cas d'intrusion car intouchable une fois qu'envoyé


III-E. Le remote debugging

remote_debugging dans le php.ini, error_log avec deuxième paramètre à 2 serveur dédié au débuggage


III-F. Personnalisations diverses

que fait track_errors dans le php.ini ? Affichage personnalisé avec error_prepend_string et error_append_string


III-G. Interception

PHP ne s'occupe plus de rien. Ni journalisation, ni filtrage par error_reporting ou @, ni arrêt du script après E_USER_ERROR -> appeler exit au besoin callback = fonction de rappel méthode : tableau à la place d'une chaîne de caractères set_error_handler, restore_error_handler ne concerne pas E_ERROR et E_PARSE, entre autres


IV. Les assertions

Digression sur les assertions Aide à la sûreté de fonctionnement A désactiver en production ?


V. Les principes d'une politique efficace


IV-A. Phase de développement

Niveau d'erreur au minimum, ne jamais masquer les erreurs, Tout montrer pour faciliter le débogage. Outil pour amener l'application à un état de bon fonctionnement importance des jeux de tests Importance des notice (exemple des indices de tableau associatif)


IV-B. Phase de production

Ne jamais afficher le détail des erreurs (raisons de sécurité), enrober l'erreur au niveau interface, logger, avertir qqn en cas de souci (niveau d'erreur significatif : moins de ressources en production qu'en développement). error reporting personnalisé utilisateurs/administrateurs ? Les erreurs permettent de détecter les problèmes transitoires et les tentatives d'attaques.


VI. Implémentation

Système permettant de switcher entre une configuration de développement et une configuration de production.


V-A. Via le fichier de configuration php.ini


V-B. Via une classe PHP


VII. Remerciements

Je tiens à remercier Yogui pour sa très grande patience.


VIII. Références

L'excellent article de Guillaume Affringue sur fr Exceptions et PHP5

PHP 5 avancé, pages de doc http://fr.php.net/manual/fr/ref.errorfunc.php



               Version PDF (Miroir)   Version hors-ligne (Miroir)

(1) Je ne suis pas tout à fait sûr de cette valeur, c'est peut-être PHP 5.2, la page de documentation d'où j'ai tirée les informations de ce tableau n'était pas tout-à-fait cohérente. Si quelqu'un veut bien installer une version 5.1, faire les tests et me communiquer ses résultats, je lui devrai évidemment une reconnaissance éternelle.
(2)ou 5.2, voir note 1.
(3)ou 5.2, voir note 1.

Valid XHTML 1.0 TransitionalValid CSS!

Copyright © 2006 Eusebius. Aucune reproduction, même partielle, ne peut être faite de ce site et 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.

Contacter le responsable de la rubrique PHP