Comment puis-je gérer analyser & mortel erreurs en utilisant un sur mesure gestionnaire d'erreurs ?
Réponses
Trop de publicités?En fait, vous pouvez gérer les erreurs d'analyse et les erreurs fatales. Il est vrai que la fonction de gestion des erreurs que vous avez définie avec set_error_handler() ne sera pas appelée. La façon de le faire est de définir une fonction d'arrêt avec register_shutdown_function(). Voici ce qui fonctionne sur mon site web :
Archivo prepend.php (ce fichier sera automatiquement ajouté à tous les scripts php scripts). Voir ci-dessous pour des conseils sur l'ajout de fichiers à PHP.
set_error_handler("errorHandler");
register_shutdown_function("shutdownHandler");
function errorHandler($error_level, $error_message, $error_file, $error_line, $error_context)
{
$error = "lvl: " . $error_level . " | msg:" . $error_message . " | file:" . $error_file . " | ln:" . $error_line;
switch ($error_level) {
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_PARSE:
mylog($error, "fatal");
break;
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
mylog($error, "error");
break;
case E_WARNING:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_USER_WARNING:
mylog($error, "warn");
break;
case E_NOTICE:
case E_USER_NOTICE:
mylog($error, "info");
break;
case E_STRICT:
mylog($error, "debug");
break;
default:
mylog($error, "warn");
}
}
function shutdownHandler() //will be called when php script ends.
{
$lasterror = error_get_last();
switch ($lasterror['type'])
{
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
case E_RECOVERABLE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_WARNING:
case E_PARSE:
$error = "[SHUTDOWN] lvl:" . $lasterror['type'] . " | msg:" . $lasterror['message'] . " | file:" . $lasterror['file'] . " | ln:" . $lasterror['line'];
mylog($error, "fatal");
}
}
function mylog($error, $errlvl)
{
...do whatever you want...
}
PHP appellera la fonction errorHandler() s'il détecte une erreur dans l'un des scripts. Si l'erreur oblige le scripts à s'arrêter immédiatement, l'erreur est gérée par la fonction shutdownHandler().
Cela fonctionne sur le site que je suis en train de développer. Je ne l'ai pas encore testé en production. Mais il capture actuellement toutes les erreurs que je trouve en le développant.
Je pense qu'il y a un risque d'attraper la même erreur deux fois, une fois par chaque fonction. Cela pourrait se produire si une erreur que je traite dans la fonction shutdownHandler() était également détectée par la fonction errorHandler().
Les TODO :
1 - Je dois travailler sur une meilleure fonction log() pour gérer les erreurs avec élégance. Parce que je suis encore en phase de développement, j'enregistre l'erreur dans une base de données et l'affiche à l'écran.
2 - Implémenter la gestion des erreurs pour tous les appels à MySQL.
3 - Mettre en place une gestion des erreurs pour mon code javascript.
NOTES IMPORTANTES :
1 - J'utilise la ligne suivante dans mon php.ini pour ajouter automatiquement le script ci-dessus à tous les script de php :
auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"
il fonctionne bien.
2 - J'enregistre et je résous toutes les erreurs, y compris les erreurs E_STRICT. Je crois au développement d'un code propre. Pendant le développement, mon fichier php.ini contient les lignes suivantes :
track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0
Lorsque je serai en ligne, je mettrai display_errors à 0 pour réduire le risque que mes utilisateurs voient de vilains messages d'erreur PHP.
J'espère que cela aidera quelqu'un.
Vous pouvez suivre ces erreurs à l'aide d'un code comme celui-ci :
(Les erreurs d'analyse ne peuvent être détectées que si elles se produisent dans la zone autres Fichiers script via include()
o require()
ou en plaçant ce code dans un auto_prepend_file
comme d'autres réponses l'ont mentionné).
function shutdown() {
$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if ($isError){
var_dump ($error);//do whatever you need with it
}
}
register_shutdown_function('shutdown');
Réponse simple : Vous ne pouvez pas. Voir le manuel :
L'erreur suivante être traités par une fonction définie par l'utilisateur : E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, et la plupart des E_STRICT soulevées dans le fichier dans lequel set_error_handler() est appelée.
Pour toute autre erreur, vous pouvez utiliser set_error_handler()
EDIT :
Puisqu'il semble qu'il y ait des discussions sur ce sujet, en ce qui concerne l'utilisation de la register_shutdown_function
Il convient donc de se pencher sur la définition de la manipulation : Pour moi, gérer une erreur signifie attraper l'erreur et réagir d'une manière qui soit "agréable" pour l'utilisateur. et les données sous-jacentes (bases de données, fichiers, services web, etc.).
Utilisation register_shutdown_function
vous ne pouvez pas gérer une erreur à partir du code où elle a été appelée, ce qui signifie que le code s'arrêterait toujours de fonctionner au moment où l'erreur se produit. Vous pouvez cependant présenter à l'utilisateur un message d'erreur au lieu d'une page blanche, mais vous ne pouvez pas, par exemple, revenir sur ce que votre code a fait avant d'échouer.
D'après les commentaires de PHP.net sur la page http://www.php.net/manual/en/function.set-error-handler.php
J'ai réalisé que quelques personnes ici ont mentionné que vous ne pouvez pas capturer les erreurs d'analyse (type 4, E_PARSE). Ce n'est pas le cas. Voici comment je procède. J'espère que cela aidera quelqu'un.
1) Créez un fichier "auto_prepend.php" dans le web Root et ajoutez ceci :
<?php
register_shutdown_function('error_alert');
function error_alert()
{
if(is_null($e = error_get_last()) === false)
{
mail('your.email@example.com', 'Error from auto_prepend', print_r($e, true));
}
}
?>
2) Ajoutez ensuite ceci "php_value fichier_auto_prepend /www/auto_prepend.php" à votre fichier fichier .htaccess dans la racine du site.
- veillez à modifier l'adresse électronique et le chemin d'accès au fichier.
Le script avec une erreur d'analyse est toujours interrompu et ne peut pas être traité. Donc si le script est appelé directement ou par include/require, il n'y a rien que vous puissiez faire. Mais s'il est appelé par AJAX, flash ou tout autre moyen, il n'y a rien à faire. es une solution de contournement pour détecter les erreurs d'analyse.
J'en avais besoin pour gérer swfupload script. Swfupload est un flash qui gère les téléchargements de fichiers et à chaque fois qu'un fichier est téléchargé, il appelle la gestion PHP script pour gérer les données de fichiers - mais il n'y a pas de sortie navigateur, donc la gestion PHP script a besoin de ces paramètres à des fins de débogage :
- avertissements et avis ob_start() ; au début et stocker le contenu dans la session par ob_get_contents() ; à la fin de la manipulation script : Ceci peut être affiché dans le navigateur par un autre script.
- erreurs fatales register_shutdown_function() pour définir la session avec la même astuce que ci-dessus
- erreurs d'analyse si la fonction ob_get_contents() est située à la fin du script de traitement et qu'une erreur d'analyse est survenue avant, la session n'est pas remplie (elle est nulle). Le script de débogage peut le gérer de cette manière :
if(!isset($_SESSION["swfupload"])) echo "parse error";
Note 1 null
significa is not set
à isset()