set_error_handler()
Apprenez à utiliser set_error_handler() en PHP pour intercepter les erreurs non fatales, les journaliser ou les convertir en exceptions.
Le comportement par défaut de PHP face à une erreur non fatale est d'afficher un message en sortie (ou de le journaliser) et de continuer l'exécution. C'est rarement ce que l'on souhaite en production : le message brut peut exposer des chemins de fichiers aux visiteurs, et vous n'avez pas d'endroit centralisé pour journaliser, formater ou convertir les erreurs. La fonction set_error_handler() résout ce problème en redirigeant les erreurs intégrées de PHP vers une fonction que vous contrôlez.
Ce chapitre explique ce que fait set_error_handler(), la signature exacte du callback attendu par PHP, les erreurs qu'il peut et ne peut pas intercepter, et comment l'utiliser pour une journalisation propre.
Ce que fait set_error_handler()
set_error_handler() enregistre un callback que PHP invoque à la place de son gestionnaire d'erreurs intégré chaque fois qu'une erreur correspondante (non fatale) est déclenchée. Votre callback décide de la suite — la journaliser, afficher un message convivial, lever une exception, ou l'ignorer silencieusement.
Elle ne stoppe pas le déclenchement des erreurs ; elle change seulement la façon dont elles sont gérées. PHP respecte toujours error_reporting pour décider s'il doit appeler votre gestionnaire.
Syntaxe
set_error_handler(
callable|null $callback,
int $error_levels = E_ALL
): callable|false| Paramètre | Description |
|---|---|
$callback | La fonction que PHP appelle quand une erreur se produit. Passez null pour restaurer le gestionnaire intégré de PHP. |
$error_levels | Un masque de bits des niveaux d'erreur que votre gestionnaire doit recevoir (ex. E_WARNING | E_NOTICE). Par défaut E_ALL. |
Valeur de retour : le gestionnaire précédemment enregistré (un callable), ou null s'il n'y en avait pas. Il retourne false uniquement si le callback est invalide.
La signature du callback
PHP appelle votre gestionnaire avec jusqu'à cinq arguments. Les quatre premiers sont ceux que vous utiliserez le plus :
function handler(
int $errno, // the error level constant, e.g. E_WARNING
string $errstr, // the error message
string $errfile = "", // file where the error occurred
int $errline = 0 // line number
): bool {
// ...
}Si votre gestionnaire retourne false, PHP poursuit son traitement d'erreur interne normal. Retourner true (ou rien) indique à PHP que l'erreur a été entièrement gérée et supprime le comportement par défaut.
Les erreurs qu'il peut intercepter
set_error_handler() intercepte les niveaux d'erreur interceptables par l'utilisateur — avertissements, notices, dépréciations, et la famille E_USER_* déclenchée par trigger_error() :
| Interceptable | Non interceptable (fatal) |
|---|---|
E_WARNING, E_NOTICE, E_DEPRECATED | E_ERROR |
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE | E_PARSE |
E_RECOVERABLE_ERROR, E_STRICT | E_CORE_ERROR, E_COMPILE_ERROR |
Remarque : Les erreurs fatales telles que
E_ERRORetE_PARSEcontournent votre gestionnaire et terminent le script. Pour capturer celles-ci, combinez votre gestionnaire avecset_exception_handler()et une fonction de shutdown. Les exceptions non capturées ne sont pas non plus routées ici — elles ont leur propre gestionnaire.
Un gestionnaire de base
Définissez une fonction avec la signature attendue et enregistrez-la. Ici, un appel à trigger_error() simule un avertissement pour que vous puissiez voir le gestionnaire s'exécuter :
<?php
function customErrorHandler($errno, $errstr, $errfile, $errline)
{
echo "Handled error [$errno]: $errstr in $errfile on line $errline\n";
return true; // we consider the error fully handled
}
set_error_handler("customErrorHandler");
trigger_error("This is a test warning", E_USER_WARNING);
// Restore PHP's default error handling
restore_error_handler();Sortie :
Handled error [512]: This is a test warning in ... on line 11512 est la valeur numérique de E_USER_WARNING. Après restore_error_handler(), les erreurs reviennent au comportement par défaut de PHP.
Conversion des erreurs en exceptions
Un pattern courant en production est de transformer les avertissements et notices en exceptions pour qu'ils transitent par votre logique try/catch habituelle. Cela vous permet de gérer un échec de file_get_contents() (qui n'émet qu'un avertissement) avec try/catch :
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
// Respect the @ operator and error_reporting settings.
if (!(error_reporting() & $errno)) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
$data = file_get_contents("/no/such/file");
} catch (ErrorException $e) {
echo "Caught: " . $e->getMessage() . "\n";
}Sortie :
Caught: file_get_contents(/no/such/file): Failed to open stream: No such file or directoryJournaliser plutôt qu'afficher
Associer la constante de niveau à un libellé lisible maintient les journaux facilement analysables. Utilisez error_log() pour écrire vers votre destination de journalisation configurée :
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
$levels = [
E_WARNING => "WARNING",
E_NOTICE => "NOTICE",
E_DEPRECATED => "DEPRECATED",
E_USER_WARNING => "USER_WARNING",
];
$label = $levels[$errno] ?? "UNKNOWN($errno)";
$line = "[$label] $errstr in $errfile:$errline";
error_log($line); // goes to your log, not the page
echo $line . "\n"; // shown here only to demonstrate the output
return true;
});
trigger_error("Disk space low", E_USER_WARNING);Sortie :
[USER_WARNING] Disk space low in ... :15Pièges à éviter
- L'opérateur
@. Quand une erreur est silencée avec@,error_reporting()retourne0dans votre gestionnaire. Vérifiezerror_reporting() & $errnosi vous souhaitez respecter@, comme montré ci-dessus. - Les erreurs fatales s'échappent toujours. Quoi qu'il en soit du second argument,
E_ERRORet les erreurs d'analyse ne sont jamais transmises à votre gestionnaire. - Il est global. Un gestionnaire enregistré affecte l'ensemble de la requête. Les bibliothèques qui définissent leur propre gestionnaire peuvent écraser le vôtre, donc restaurez les gestionnaires quand vous avez terminé.
- N'utilisez pas
echoen production. Afficher des messages bruts expose des chemins et aide les attaquants — journalisez-les et affichez plutôt une page générique.
Fonctions associées
restore_error_handler()— revenir au gestionnaire précédent.trigger_error()— déclencher vos propres erreursE_USER_*.error_reporting()— contrôler les niveaux actifs.set_exception_handler()— capturer les exceptions non capturées.
Conclusion
set_error_handler() vous offre un seul endroit pour intercepter les erreurs non fatales de PHP et y appliquer votre propre logique — les journaliser, les convertir en exceptions, ou les masquer aux utilisateurs. Associez-la à un gestionnaire d'exceptions et une journalisation appropriée pour une gestion des erreurs de niveau production. N'oubliez pas sa seule limite absolue : les erreurs fatales et les erreurs d'analyse la contournent entièrement.