W3docs

set_error_handler()

Scopri come usare set_error_handler() in PHP per intercettare errori non fatali, registrarli e convertirli in eccezioni.

Il comportamento predefinito di PHP in caso di errore non fatale è quello di stampare un messaggio nell'output (o registrarlo) e continuare l'esecuzione. Questo è raramente quello che si vuole in produzione: il messaggio grezzo può rivelare percorsi di file ai visitatori, e non si dispone di un luogo centralizzato per registrare, formattare o convertire gli errori. La funzione set_error_handler() risolve questo problema instradando gli errori integrati di PHP attraverso una funzione sotto il tuo controllo.

Questo capitolo spiega cosa fa set_error_handler(), la firma esatta del callback che PHP si aspetta, quali errori può e non può intercettare, e come usarla per una registrazione pulita.

Cosa fa set_error_handler()

set_error_handler() registra un callback che PHP invoca al posto del suo gestore di errori integrato ogni volta che viene sollevato un errore (non fatale) corrispondente. Il tuo callback decide cosa succede dopo — registrarlo, visualizzare un messaggio amichevole, lanciare un'eccezione o ignorarlo silenziosamente.

Non impedisce che gli errori vengano sollevati; cambia solo il modo in cui vengono gestiti. PHP rispetta ancora error_reporting nel decidere se chiamare il tuo gestore.

Sintassi

set_error_handler(
    callable|null $callback,
    int $error_levels = E_ALL
): callable|false
ParametroDescrizione
$callbackLa funzione che PHP chiama quando si verifica un errore. Passa null per ripristinare il gestore integrato di PHP.
$error_levelsUna maschera di bit dei livelli di errore che il tuo gestore dovrebbe ricevere (es. E_WARNING | E_NOTICE). Il valore predefinito è E_ALL.

Valore restituito: il gestore precedentemente registrato (un callable), oppure null se non ce n'era nessuno. Restituisce false solo quando il callback non è valido.

La firma del callback

PHP chiama il tuo gestore con fino a cinque argomenti. I primi quattro sono quelli che utilizzerai più spesso:

function handler(
    int $errno,        // the error level constant, e.g. E_WARNING
    string $errstr,    // the error message
    string $errfile = "",   // file where the error occurred
    int $errline = 0        // line number
): bool {
    // ...
}

Se il tuo gestore restituisce false, PHP continua con la sua normale gestione interna degli errori. Restituire true (o nulla) dice a PHP che l'errore è stato completamente gestito e sopprime il comportamento predefinito.

Quali errori può intercettare

set_error_handler() intercetta i livelli di errore intercettabili dall'utente — avvisi, avvisi, deprecazioni e la famiglia E_USER_* sollevata da trigger_error():

IntercettabiliNon intercettabili (fatali)
E_WARNING, E_NOTICE, E_DEPRECATEDE_ERROR
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICEE_PARSE
E_RECOVERABLE_ERROR, E_STRICTE_CORE_ERROR, E_COMPILE_ERROR

Nota: Gli errori fatali come E_ERROR e E_PARSE bypassano il tuo gestore e terminano lo script. Per catturarli, combina il tuo gestore con set_exception_handler() e una funzione di shutdown. Le eccezioni non catturate non vengono instradate qui — hanno il proprio gestore.

Un gestore di base

Definisci una funzione con la firma attesa e registrala. Qui una chiamata a trigger_error() simula un avviso in modo da poter vedere il gestore in esecuzione:

<?php

function customErrorHandler($errno, $errstr, $errfile, $errline)
{
    echo "Handled error [$errno]: $errstr in $errfile on line $errline\n";
    return true; // we consider the error fully handled
}

set_error_handler("customErrorHandler");

trigger_error("This is a test warning", E_USER_WARNING);

// Restore PHP's default error handling
restore_error_handler();

Output:

Handled error [512]: This is a test warning in ... on line 11

512 è il valore numerico di E_USER_WARNING. Dopo restore_error_handler(), gli errori tornano al comportamento predefinito di PHP.

Conversione degli errori in eccezioni

Un pattern di produzione comune è quello di trasformare avvisi e avvisi in eccezioni in modo che fluiscano attraverso la normale logica try/catch. Questo ti permette di gestire un file_get_contents() fallito (che emette solo un avviso) con try/catch:

<?php

set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    // Respect the @ operator and error_reporting settings.
    if (!(error_reporting() & $errno)) {
        return false;
    }
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

try {
    $data = file_get_contents("/no/such/file");
} catch (ErrorException $e) {
    echo "Caught: " . $e->getMessage() . "\n";
}

Output:

Caught: file_get_contents(/no/such/file): Failed to open stream: No such file or directory

Registrazione invece della visualizzazione

Mappare la costante del livello su un'etichetta leggibile mantiene i log analizzabili. Usa error_log() per scrivere nella destinazione di log configurata:

<?php

set_error_handler(function ($errno, $errstr, $errfile, $errline) {
    $levels = [
        E_WARNING       => "WARNING",
        E_NOTICE        => "NOTICE",
        E_DEPRECATED    => "DEPRECATED",
        E_USER_WARNING  => "USER_WARNING",
    ];
    $label = $levels[$errno] ?? "UNKNOWN($errno)";

    $line = "[$label] $errstr in $errfile:$errline";
    error_log($line);   // goes to your log, not the page
    echo $line . "\n";  // shown here only to demonstrate the output
    return true;
});

trigger_error("Disk space low", E_USER_WARNING);

Output:

[USER_WARNING] Disk space low in ... :15

Insidie

  • L'operatore @. Quando un errore viene silenziato con @, error_reporting() restituisce 0 all'interno del tuo gestore. Controlla error_reporting() & $errno se vuoi rispettare @, come mostrato sopra.
  • Gli errori fatali sfuggono comunque. Indipendentemente dal secondo argomento, E_ERROR e gli errori di analisi non vengono mai consegnati al tuo gestore.
  • È globale. Un gestore registrato influisce sull'intera richiesta. Le librerie che impostano il proprio gestore possono sovrascrivere il tuo, quindi ripristina i gestori quando hai finito.
  • Non usare echo in produzione. La visualizzazione di messaggi grezzi rivela percorsi e aiuta gli aggressori — registrali e mostra invece una pagina generica.

Funzioni correlate

Conclusione

set_error_handler() ti fornisce un unico punto per intercettare gli errori non fatali di PHP e applicare la tua logica — registrarli, convertirli in eccezioni o nasconderli agli utenti. Abbinala a un gestore di eccezioni e alla registrazione appropriata per una gestione degli errori di livello produzione. Ricorda il suo unico limite fisso: gli errori fatali e di analisi la bypassano completamente.

Pratica

Pratica
In PHP, cosa fa la funzione set_error_handler()?
In PHP, cosa fa la funzione set_error_handler()?
Was this page helpful?