Pregunta

Según el comentario sobre esta respuesta es posible detectar errores fatales a través de un apagado función que no puede ser capturado con set_error_handler().

Sin embargo, no pude encontrar la manera de determinar si el cierre se ha producido debido a un error grave o debido a la secuencia de comandos de llegar a su fin.

Además, las funciones de depuración backtrace parecen estar extinta en la función de desconexión, por lo que es bastante inútil para registrar el seguimiento de la pila donde el error fatal ocurrió.

Así que mi pregunta es: ¿cuál es la mejor manera de reaccionar en errores fatales (especialmente llamadas a funciones no definidas), manteniendo la capacidad de crear una traza adecuada

¿Fue útil?

Solución

Esto funciona para mí:

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

Sin embargo, es probable que lo saben ya, pero sólo para asegurarse: usted no puede recuperarse de una E_ERROR de ninguna manera

.

En cuanto a la traza, no se puede ... :( En la mayoría de los casos de un error fatal, sobre todo Indefinido función errores, que en realidad no lo necesitan. Pinpointing el archivo / línea donde se ha producido es suficiente. La traza es irrelevante en este caso.

Otros consejos

Una forma de distinguir entre error fatal y apagado de la aplicación adecuada con el register_shutdown_function es definir una constante como la última línea de su programa y, a continuación, comprobar si se define 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 el programa llega al final, no podría haber encontrado un error grave, por lo que sabemos que no se ejecute la función, si se define la constante.

error_get_last () es una matriz con toda la información sobre el error fatal que lo que necesitará para depurar, a pesar de que no tendrá un trazado inverso, como se ha mencionado.

En general, si su programa php ha encontrado un error grave (en comparación con una excepción), desea que el programa para hacer estallar para que pueda encontrar y solucionar el problema. He encontrado register_shutdown_function útil para entornos de producción en la que desea el informe de errores fuera, pero quiero un poco de manera de registrar el error en el fondo para que pueda responder a ella. También es posible usar la función de dirigir al usuario a una página HTML amistosa en el caso de un error tal manera que no sólo sirven a una página en blanco.

Tan sólo un buen truco para conseguir el método actual gestor_errores =)

<?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;
    }
}
?>

También me wa no tener en cuenta que si se llama

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

PHP deja de mostrar el error, de lo contrario el texto de error será enviado al cliente antes de su gestor de errores

Yo uso "ob_start" para esto.

function fatal_error_handler($buffer) {
    if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs) ) {
        //Your code
    }
    return $buffer;
}
ob_start("fatal_error_handler");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top