Pour afficher les erreurs PHP, placez ces lignes en haut de votre script : ini_set('display_errors', '1'); et error_reporting(E_ALL);. La première demande à PHP d'afficher les messages d'erreur, la seconde de signaler tous les types d'erreurs, y compris les warnings et les dépréciations.
<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
Une fois cela en place, une erreur comme la lecture d'une variable jamais définie affiche un message avec le fichier et le numéro de ligne, au lieu d'échouer en silence :
Warning: Undefined variable $total in /home/index.php on line 7
error_reporting() appelée sans argument renvoie le réglage actuel sous forme de nombre. Cliquez sur Run pour définir un niveau et le retraduire en noms :
Chaque type d'erreur correspond à un bit, donc E_ALL & ~E_DEPRECATED signifie « tout sauf les dépréciations ». Remplacez la première ligne par error_reporting(E_ERROR | E_WARNING); et relancez.
Afficher les erreurs dans php.ini
Un réglage dans le script ne s'applique qu'une fois le script lancé. Pour afficher les erreurs de tous les scripts, erreurs de syntaxe comprises, modifiez php.ini (trouvez-le avec php --ini) :
; Development
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
Redémarrez Apache ou PHP-FPM après la modification. Le serveur intégré php -S et la ligne de commande relisent le fichier à chaque démarrage. Sur un hébergement mutualisé sans accès à php.ini, Apache avec mod_php accepte aussi des lignes dans .htaccess :
php_flag display_errors on
php_value error_reporting -1
-1 active tous les bits, ce qui revient à E_ALL.
Les niveaux d'erreur
| Constante | Ce qui la déclenche | Arrête le script |
|---|---|---|
E_ERROR | Erreur fatale à l'exécution, comme un manque de mémoire | oui |
E_PARSE | Erreur de syntaxe dans le fichier | oui |
E_WARNING | Variable ou clé de tableau non définie, fichier manquant dans include | non |
E_NOTICE | Problèmes mineurs (il en reste peu en PHP 8) | non |
E_DEPRECATED | Code qu'une future version de PHP refusera | non |
E_USER_* | Erreurs que vous déclenchez avec trigger_error() | seulement E_USER_ERROR |
E_ALL | Tous les niveaux, y compris les erreurs du noyau et de compilation non listées ici |
PHP 8.0 a transformé beaucoup d'anciens warnings en exceptions : diviser par zéro avec / et passer un mauvais type à une fonction native lèvent désormais une sous-classe d'Error, comme l'appel d'une fonction non définie depuis PHP 7. Vous pouvez intercepter les trois :
Les exceptions sont expliquées dans try et catch. Les warnings, notices et dépréciations passent toujours par le système de signalement d'erreurs décrit ici.
Journaliser les erreurs au lieu de les afficher
Sur un site en ligne, les visiteurs ne doivent jamais voir de messages d'erreur : ils révèlent des chemins, du SQL et du code. Écrivez-les plutôt dans un fichier journal :
; Production
display_errors = Off
log_errors = On
error_log = /var/log/php/app-errors.log
error_reporting = E_ALL
Gardez error_reporting = E_ALL en production. Baisser ce niveau ne fait pas disparaître les erreurs, cela vous empêche seulement d'en entendre parler. Vos propres messages peuvent aller dans le même journal avec error_log() :
<?php
error_log("Payment failed for order 1042");
Surveillez ensuite le fichier pendant vos tests : tail -f /var/log/php/app-errors.log.
Transformer les warnings en exceptions avec set_error_handler
set_error_handler remplace le traitement par défaut des warnings, notices et dépréciations par votre propre fonction. Un modèle courant les convertit tous en ErrorException, si bien qu'une clé de tableau oubliée arrête le code comme n'importe quelle autre exception et peut être interceptée :
Le gestionnaire reçoit le niveau d'erreur en premier argument, il peut donc traiter les niveaux différemment. Celui-ci se contente de journaliser les dépréciations et transforme tout le reste en exception :
Les erreurs fatales et les erreurs de syntaxe n'atteignent jamais le gestionnaire, car le script ne peut pas continuer après elles. Pour les enregistrer, déclarez une fonction d'arrêt qui lit error_get_last().
Lire la dernière erreur avec error_get_last
Certaines fonctions renvoient false et ne donnent la raison que sous forme de warning, par exemple file_get_contents sur un fichier manquant. error_get_last() renvoie ce warning sous forme de tableau, ce qui est utile quand vous voulez afficher votre propre message :
L'opérateur @ placé devant l'appel supprime le message pour cette seule expression. Utilisez-le avec parcimonie et uniquement quand vous vérifiez le résultat juste après, comme ici ; un @ seul ne fait que cacher des bugs.
Erreur fréquente : les erreurs sont activées, mais la page reste blanche
Si vous avez ajouté ini_set('display_errors', '1') et voyez toujours une page blanche, l'erreur est probablement une erreur de syntaxe. PHP analyse tout le fichier avant d'exécuter la première ligne, donc un ; ou une } manquant arrête tout avant que ini_set ne s'exécute. Vérifiez le fichier depuis le terminal, qui affiche toujours le message :
php -l index.php
Errors parsing index.php
PHP Parse error: syntax error, unexpected token "," in index.php on line 2
Le numéro de ligne indique l'endroit où PHP a abandonné, souvent la ligne qui suit la véritable erreur. Corrigez-la, relancez php -l jusqu'à ce qu'il affiche No syntax errors detected, puis rechargez la page.
Questions fréquentes
Comment afficher toutes les erreurs en PHP ?
Ajoutez ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); tout en haut du script, ou réglez display_errors = On et error_reporting = E_ALL dans php.ini et redémarrez le serveur web ou PHP-FPM.
Pourquoi ma page PHP affiche-t-elle un écran blanc ?
Une erreur fatale a arrêté le script alors que display_errors est désactivé, donc rien n'a été affiché. Activez les erreurs (ou lisez le journal d'erreurs, par exemple avec tail -f sur le fichier indiqué par error_log) pour voir le message et le numéro de ligne.
Pourquoi ini_set('display_errors', 1) n'affiche pas mon erreur de syntaxe ?
Une erreur de syntaxe arrête PHP avant l'exécution de la moindre ligne du fichier, donc l'appel à ini_set n'a jamais lieu. Réglez display_errors dans php.ini, ou placez le ini_set dans un petit fichier qui fait ensuite un include du fichier cassé.
Faut-il activer display_errors en production ?
Non. Les messages d'erreur révèlent des chemins de fichiers et des détails du code aux visiteurs. En production, utilisez display_errors = Off, log_errors = On et un chemin error_log, et gardez error_reporting = E_ALL pour que les problèmes soient toujours enregistrés.
Que fait error_reporting(0) ?
Il désactive le signalement de tous les types d'erreurs pour le reste du script, si bien que les warnings et même les erreurs fatales ne produisent aucun message. Cela cache les problèmes au lieu de les corriger ; préférez journaliser les erreurs plutôt que de les faire taire.