Domanda

Secondo il commento su questa risposta è possibile rilevare gli errori fatali attraverso un shutdown funzione che non può essere catturato con set_error_handler().

Tuttavia, non riuscivo a trovare il modo di determinare se l'arresto si è verificato a causa di un errore fatale o per la sceneggiatura di raggiungere la sua fine.

Inoltre, le funzioni di debug backtrace sembrano essere defunta nella funzione di spegnimento, il che rende abbastanza inutile per la registrazione della traccia dello stack in cui si è verificato l'errore fatale.

Quindi la mia domanda è: qual è il modo migliore per reagire a errori irreversibili (specialmente chiamate funzione non definita), mantenendo la possibilità di creare un backtrace corretto

È stato utile?

Soluzione

Questo funziona per me:

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

Tuttavia, probabilmente sapete già, ma solo per assicurarsi che: non è possibile recuperare da un'E_ERROR in alcun modo

.

Per quanto riguarda il backtrace, non è possibile ... :( Nella maggior parte dei casi di un errore fatale, in particolare Funzione non definita di errori, non si ha realmente bisogno. Individuare il file / linea dove si è verificato è sufficiente. Il backtrace è irrilevante in questo caso.

Altri suggerimenti

Un modo per distinguere tra errore fatale e la corretta chiusura dell'applicazione con la register_shutdown_function è quello di definire una costante come l'ultima riga del programma, e quindi verificare se la costante è definita:

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

register_shutdown_function('fatal_error');

define('PROGRAM_EXECUTION_SUCCESSFUL', true);

Se il programma raggiunge la fine, non poteva essersi verificato un errore fatale, quindi sappiamo di non eseguire la funzione se la costante è definita.

error_get_last () è una matrice con tutte le informazioni riguardanti l'errore fatale che dovreste aver bisogno di eseguire il debug, anche se non avrà un backtrace, come è stato detto.

In generale, se il programma php si è verificato un errore irreversibile (al contrario di un'eccezione), si desidera che il programma per saltare in aria in modo da poter individuare e risolvere il problema. Ho trovato register_shutdown_function utile per gli ambienti di produzione in cui si desidera la segnalazione degli errori fuori, ma voglio un modo per registrare l'errore in background in modo che si può rispondere ad essa. Si potrebbe anche usare la funzione di indirizzare l'utente a una pagina html amichevole in caso di un tale errore in modo che non si limitano a servire una pagina vuota.

Proprio un bel trucco per ottenere il metodo error_handler corrente =)

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

Anche io wa non notare che se si chiama

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

Php smette di visualizzare l'errore, altrimenti il ??testo di errore verrà inviato al cliente prima del vostro gestore degli errori

Io uso "ob_start" per questo.

function fatal_error_handler($buffer) {
    if (preg_match("|(Fatal error:)(.+)|", $buffer, $regs) ) {
        //Your code
    }
    return $buffer;
}
ob_start("fatal_error_handler");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top