Domanda

Come posso gestire analizzare & fatale errori utilizzando a costume gestore degli errori?

È stato utile?

Soluzione

Risposta semplice:Non puoi.Vedi il Manuale:

I seguenti tipi di errore non possono essere Gestito con una funzione definita dall'utente:E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING e la maggior parte dei E_STRICT sollevata nel fascicolo in cui set_error_handler() viene chiamato.

Per ogni altro errore, puoi usare set_error_handler()

MODIFICARE:

Poiché sembra che ci siano alcune discussioni su questo argomento, per quanto riguarda l'utilizzo register_shutdown_function, dovremmo dare un'occhiata alla definizione di manipolazione:Per me, gestire un errore significa cogliere l'errore e reagire in un modo che sia "gentile" per l'utente E i dati sottostanti (banche dati, file, servizi web, ecc.).

Utilizzando register_shutdown_function non è possibile gestire un errore dall'interno del codice in cui è stato chiamato, il che significa che il codice smetterebbe di funzionare nel punto in cui si verifica l'errore.Puoi, tuttavia, presentare all'utente un messaggio di errore invece di una pagina bianca, ma non puoi, ad esempio, ripristinare tutto ciò che il tuo codice ha fatto prima del fallimento.

Altri suggerimenti

In realtà puoi gestire errori di analisi ed errori fatali.È vero che la funzione di gestione degli errori definita con set_error_handler() non verrà chiamata.Il modo per farlo è definire una funzione di shutdown con Register_shutdown_function().Ecco cosa ho lavorato nel mio sito web:

File anteporre.php (questo file verrà anteposto automaticamente a tutti gli script php).Vedi sotto per suggerimenti su come anteporre i file a 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 chiamerà la funzione errorHandler() se rileva un errore in uno qualsiasi degli script.Se l'errore forza l'arresto immediato dello script, l'errore viene gestito dalla funzione shutdownHandler().

Questo sta lavorando sul sito che ho in fase di sviluppo.Non l'ho ancora testato in produzione.Ma attualmente sta rilevando tutti gli errori che trovo durante lo sviluppo.

Credo che esista il rischio di rilevare lo stesso errore due volte, una volta per ciascuna funzione.Ciò potrebbe accadere se un errore che sto gestendo nella funzione shutdownHandler() veniva rilevato anche dalla funzione errorHandler().

TODO:

1 - Devo lavorare su una funzione log() migliore per gestire gli errori con garbo.Poiché sono ancora in fase di sviluppo, fondamentalmente registro l'errore in un database e lo riproduco sullo schermo.

2 - Implementare la gestione degli errori per tutte le chiamate MySQL.

3 - Implementa la gestione degli errori per il mio codice JavaScript.

NOTE IMPORTANTI:

1 - Sto utilizzando la seguente riga nel mio php.ini per anteporre automaticamente lo script sopra a tutti gli script php:

auto_prepend_file = "/homepages/45/d301354504/htdocs/hmsee/cgi-bin/errorhandling.php"

Funziona bene.

2 - Sto registrando e risolvendo tutti gli errori, inclusi gli errori E_STRICT.Credo nello sviluppo di un codice pulito.Durante lo sviluppo, il mio file php.ini ha le seguenti righe:

track_errors = 1
display_errors = 1
error_reporting = 2147483647
html_errors = 0

Quando andrò in diretta, modificherò display_errors su 0 per ridurre il rischio che i miei utenti vedano brutti messaggi di errore PHP.

Spero che questo aiuti qualcuno.

Puoi tenere traccia di questi errori utilizzando un codice come questo:

(Gli errori di analisi possono essere rilevati solo se si verificano in altro file di script tramite include() O require(), o inserendo questo codice in un file auto_prepend_file come hanno menzionato altre risposte.)

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');

Dai commenti di PHP.net sulla pagina http://www.php.net/manual/en/function.set-error-handler.php

Mi sono reso conto che alcune persone qui hanno affermato che non è possibile acquisire errori di analisi (tipo 4, E_PARSE).Questo non è vero.Ecco come faccio.Spero che questo aiuti qualcuno.

1) Crea un file "auto_prepend.php" nella radice web e aggiungi questo:

<?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) Quindi aggiungi questo "php_value auto_prepend_file /www/auto_prepend.php" al tuo .htaccess nella directory principale del web.

  • assicurati di modificare l'indirizzo email e il percorso del file.

Dalla mia esperienza puoi rilevare tutti i tipi di errori, nascondere il messaggio di errore predefinito e visualizzare un tuo messaggio di errore (se lo desideri).Di seguito sono elencate le cose di cui hai bisogno.

1) Uno script di livello iniziale/superiore, chiamiamolo così index.php dove memorizzi le funzioni personalizzate del gestore degli errori.I gestori delle funzioni di errore personalizzate devono rimanere in alto in modo da rilevare gli errori sotto di loro, con "sotto" intendo i file inclusi.

2) Il presupposto che questo script principale sia privo di errori deve essere vero!questo è molto importante, non puoi rilevare errori fatali index.php quando viene trovata la funzione di gestione degli errori personalizzata index.php.

3) Direttive Php (devono essere trovate anche in index.php) set_error_handler("myNonFatalErrorHandler"); #per individuare errori non fataliregister_shutdown_function('myShutdown'); #per individuare errori fataliini_set('display_errors', false); #per nascondere gli errori mostrati all'utente da phpini_set('log_errors',FALSE); #assumendo che registriamo noi stessi gli erroriini_set('error_reporting', E_ALL); #Ci piace segnalare tutti gli errori

mentre in produzione (se non sbaglio) possiamo partire ini_set('error_reporting', E_ALL); così com'è per poter registrare gli errori, nello stesso tempo ini_set('display_errors', false); si assicurerà che nessun errore venga visualizzato all'utente.

Per quanto riguarda il contenuto effettivo delle due funzioni di cui sto parlando, myNonFatalErrorHandler E myShutdown, Non inserisco qui contenuti dettagliati per mantenere le cose semplici.Inoltre gli altri visitatori hanno fornito molti esempi.Mostro solo un'idea molto semplice.

function myNonFatalErrorHandler($v, $m, $f, $l, $c){
 $some_logging_var_arr1[]="format $v, $m, $f, ".$err_lvl[$l].", $c the way you like";
 //You can display the content of $some_logging_var_arr1 at the end of execution too.
}

function myShutdown()
{
  if( ($e=error_get_last())!==null ){
      $some_logging_var_arr2= "Format the way you like:". $err_level[$e['type']].$e['message'].$e['file'].$e['line'];
  }
//display $some_logging_var_arr2 now or later, e.g. from a custom session close function
}

per quanto riguarda $err_lvl può essere:

$err_lvl = array(E_ERROR=>'E_ERROR', E_CORE_ERROR=>'E_CORE_ERROR', E_COMPILE_ERROR=>'E_COMPILE_ERROR', E_USER_ERROR=>'E_USER_ERROR', E_PARSE=>'E_PARSE', E_RECOVERABLE_ERROR=>'E_RECOVERABLE_ERROR', E_WARNING=>'E_WARNING', E_CORE_WARNING=>'E_CORE_WARNING', E_COMPILE_WARNING=>'E_COMPILE_WARNING',
E_USER_WARNING=>'E_USER_WARNING', E_NOTICE=>'E_NOTICE', E_USER_NOTICE=>'E_USER_NOTICE',E_STRICT=>'E_STRICT');

Lo script con errore di analisi viene sempre interrotto e non può essere gestito.Quindi, se lo script viene chiamato direttamente o tramite include/require, non puoi fare nulla.Ma se viene chiamato da AJAX, flash o in qualsiasi altro modo, lì È una soluzione alternativa su come rilevare gli errori di analisi.

Avevo bisogno di questo da gestire swfload sceneggiatura.Swfupload è un flash che gestisce i caricamenti di file e ogni volta che un file viene caricato, chiama lo script di gestione PHP per gestire i dati dei file, ma non c'è output del browser, quindi lo script di gestione PHP necessita di queste impostazioni per scopi di debug:

  • avvisi e avvisi ob_inizio();all'inizio e memorizza il contenuto nella sessione con ob_get_contents();alla fine dello script di gestione:Questo può essere visualizzato nel browser da un altro script
  • errori fatali Register_shutdown_function() per impostare la sessione con lo stesso trucco di cui sopra
  • analizzare gli errori se ob_get_contents() si trova alla fine dello script di gestione e si è verificato un errore di analisi prima, la sessione non viene riempita (è nulla).Lo script di debug può gestirlo in questo modo: if(!isset($_SESSION["swfupload"])) echo "parse error";

Nota 1 null significa is not set A isset()

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top