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| Parametro | Descrizione |
|---|---|
$callback | La funzione che PHP chiama quando si verifica un errore. Passa null per ripristinare il gestore integrato di PHP. |
$error_levels | Una 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():
| Intercettabili | Non intercettabili (fatali) |
|---|---|
E_WARNING, E_NOTICE, E_DEPRECATED | E_ERROR |
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE | E_PARSE |
E_RECOVERABLE_ERROR, E_STRICT | E_CORE_ERROR, E_COMPILE_ERROR |
Nota: Gli errori fatali come
E_ERROReE_PARSEbypassano il tuo gestore e terminano lo script. Per catturarli, combina il tuo gestore conset_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 11512 è 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 directoryRegistrazione 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 ... :15Insidie
- L'operatore
@. Quando un errore viene silenziato con@,error_reporting()restituisce0all'interno del tuo gestore. Controllaerror_reporting() & $errnose vuoi rispettare@, come mostrato sopra. - Gli errori fatali sfuggono comunque. Indipendentemente dal secondo argomento,
E_ERRORe 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
echoin produzione. La visualizzazione di messaggi grezzi rivela percorsi e aiuta gli aggressori — registrali e mostra invece una pagina generica.
Funzioni correlate
restore_error_handler()— ripristina il gestore precedente.trigger_error()— solleva i tuoi erroriE_USER_*.error_reporting()— controlla quali livelli sono attivi.set_exception_handler()— cattura le eccezioni non gestite.
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.