Question

Selon le commentaire sur cette réponse il est possible d'attraper des erreurs fatales à travers une fonction arrêt qui ne peut être pris en utilisant set_error_handler().

Cependant, je ne pouvais pas savoir comment déterminer si l'arrêt est survenue en raison d'une erreur fatale ou en raison du script atteint sa fin.

En outre, les fonctions de débogage backtrace semblent être disparu dans la fonction d'arrêt, ce qui rend assez inutile pour se connecter la trace de la pile où l'erreur fatale est survenue.

Alors ma question est: quelle est la meilleure façon de réagir sur des erreurs fatales (en particulier les appels de fonctions non définies) tout en gardant la possibilité de créer une pile appropriée

Était-ce utile?

La solution

Cela fonctionne pour moi:

function shutdown() {
    $error = error_get_last();
    if ($error['type'] === E_ERROR) {
        // fatal error has occured
    }
}

register_shutdown_function('shutdown');

spl_autoload_register('foo'); 
// throws a LogicException which is not caught, so triggers a E_ERROR

Cependant, vous savez sans doute déjà, mais juste pour vous assurer que vous ne pouvez pas récupérer d'une E_ERROR de quelque façon que

.

En ce qui concerne la rétrospection, vous ne pouvez pas ... :( Dans la plupart des cas d'une erreur fatale, en particulier Fonction non définie erreurs, vous ne vraiment pas besoin. Fichier Repérer / ligne où elle est produite est suffisant. La trace est sans importance dans ce cas.

Autres conseils

Une façon de distinguer entre l'erreur fatale et l'arrêt de l'application correcte avec le register_shutdown_function est de définir une constante comme la dernière ligne de votre programme, puis vérifier si elle est définie la constante:

function fatal_error() {
if ( ! defined(PROGRAM_EXECUTION_SUCCESSFUL)) {
        // fatal error has occurred
    }
}

register_shutdown_function('fatal_error');

define('PROGRAM_EXECUTION_SUCCESSFUL', true);

Si le programme arrive à la fin, il ne pouvait pas avoir rencontré une erreur fatale, donc nous savons ne pas exécuter la fonction si elle est définie la constante.

error_get_last () est un tableau avec toutes les informations concernant l'erreur fatale que vous avez besoin de déboguer, mais il ne sera pas un backtrace, comme cela a été mentionné.

En général, si votre programme php a rencontré une erreur fatale (par opposition à une exception), vous souhaitez que le programme pour faire sauter afin que vous puissiez trouver et résoudre le problème. J'ai trouvé register_shutdown_function utile pour les environnements de production où vous voulez erreur de déclaration hors, mais que vous voulez un moyen de connecter l'erreur dans l'arrière-plan afin que vous puissiez y répondre. Vous pouvez également utiliser la fonction de diriger l'utilisateur vers une page html conviviale en cas d'une telle erreur afin que vous ne servez pas seulement une page blanche.

Juste une belle astuce pour obtenir la méthode error_handler actuelle =)

<?php
register_shutdown_function('__fatalHandler');
function __fatalHandler()
{
    $error      = error_get_last();

    //check if it's a core/fatal error, otherwise it's a normal shutdown
    if($error !== NULL && $error['type'] === E_ERROR) {
        //Bit hackish, but the set_exception_handler will return the old handler
        function fakeHandler() { }
        $handler = set_exception_handler('fakeHandler');
        restore_exception_handler();
        if($handler !== null) { 
            call_user_func($handler, new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
        }
        exit;
    }
}
?>

i wan't également à noter que si vous appelez

<?php
ini_set('display_errors', false);
?>

Php cesse d'afficher l'erreur, sinon le texte d'erreur sera envoyée au client avant votre gestionnaire d'erreurs

Je l'utilise pour cette "ob_start".

function fatal_error_handler($buffer) {
    if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs) ) {
        //Your code
    }
    return $buffer;
}
ob_start("fatal_error_handler");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top