W3docs

set_exception_handler()

Come set_exception_handler() di PHP registra un gestore globale per eccezioni non catturate, con firma, valore restituito, esempio pratico e best practice.

Introduzione

set_exception_handler() registra una funzione che PHP chiama ogni volta che un'eccezione non catturata raggiunge il livello più alto dello script. Normalmente un'eccezione non catturata produce un errore fatale e uno stack trace predefinito; un gestore globale consente di sostituire tutto ciò con una registrazione consistente, una pagina di errore amichevole o un sistema di notifica — in un unico punto, per l'intera applicazione. Questa pagina tratta la firma della funzione, il valore restituito, un esempio eseguibile, i casi che non gestisce e le insidie da conoscere.

Se hai bisogno prima delle basi su come lanciare e catturare eccezioni, inizia con Eccezioni PHP e il capitolo try/catch.

Quando viene chiamato il gestore?

Una normale eccezione viene catturata dal primo blocco catch corrispondente. Il gestore globale viene eseguito solo quando nessun blocco catch corrisponde — l'eccezione "sfugge" fino in cima allo script:

try {
    throw new RuntimeException('handled here');
} catch (RuntimeException $e) {
    // caught locally — the global handler never runs
}

throw new RuntimeException('nothing catches this'); // → global handler runs, then script ends

Dopo che il gestore ritorna, l'esecuzione non riprende — lo script termina. Il gestore è quindi la tua ultima possibilità per registrare e presentare l'errore in modo pulito, non un modo per recuperare e continuare.

Firma e valore restituito

set_exception_handler(?callable $callback): ?callable
  • $callback — un callable che accetta l'oggetto lanciato come unico argomento. Da PHP 7 ogni eccezione ed errore implementa Throwable, quindi è consigliabile usare Throwable come type-hint del parametro (non solo Exception) per catturare anche le istanze di Error come TypeError.
  • Restituisce il gestore registrato in precedenza (o null se nessuno era impostato), che puoi conservare per ripristinarlo in seguito. Passare null rimuove il gestore.

Esempio eseguibile

Lo script seguente registra un gestore, lo attiva con un'eccezione non catturata e stampa un messaggio formattato. Scrive sull'errore standard tramite error_log() senza destinazione, quindi è completamente portabile:

<?php

function appExceptionHandler(Throwable $e): void
{
    $message = sprintf(
        "Uncaught %s: %s in %s on line %d",
        get_class($e),
        $e->getMessage(),
        $e->getFile(),
        $e->getLine()
    );

    error_log($message);            // goes to the SAPI error log / stderr
    echo "Something went wrong.\n"; // user-facing message
}

set_exception_handler('appExceptionHandler');

throw new RuntimeException('Database is unreachable');

Output (la riga error_log va a stderr, echo a stdout):

Something went wrong.

con una riga come Uncaught RuntimeException: Database is unreachable in /path/to/script.php on line 19 nel log degli errori.

Cosa NON gestisce

set_exception_handler() intercetta solo le eccezioni non catturate. Non cattura:

  • Errori fatali, errori di analisi o avvisi — questi passano attraverso set_error_handler() (per gli errori catturabili) o register_shutdown_function() (per i fatali).
  • Le eccezioni già catturate da un blocco try/catch locale.

Per errori non-eccezione come avvisi e notifiche, registra un gestore separato con set_error_handler().

Ripristino del gestore precedente

restore_exception_handler() ripristina il gestore che era attivo prima dell'ultima chiamata a set_exception_handler(). Usalo quando un gestore personalizzato deve applicarsi solo a un blocco di codice specifico:

<?php

set_exception_handler(function (Throwable $e) {
    echo "Custom: {$e->getMessage()}\n";
});

// ... code that should use the custom handler ...

restore_exception_handler(); // back to the default behavior

Importante: il tuo gestore non deve lanciare una nuova eccezione. In caso contrario, PHP non può distribuirla nuovamente e genera invece un errore fatale.

Best Practice per l'uso di set_exception_handler

Quando si utilizza set_exception_handler, ci sono alcune best practice da seguire per garantire che l'applicazione gestisca gli errori in modo efficace:

  1. Usa Throwable come type-hint del parametro del gestore in modo da catturare sia i sottotipi di Exception che di Error (PHP 7+).
  2. Assicurati che il gestore non lanci mai una nuova eccezione — ciò causerebbe un errore fatale non recuperabile.
  3. Registra abbastanza contesto per diagnosticare il problema: classe dell'eccezione, messaggio, file, riga e lo stack trace da $e->getTraceAsString().
  4. Mantieni il messaggio rivolto all'utente generico; non esporre mai stack trace o messaggi agli utenti finali in produzione.
  5. Registra il gestore il prima possibile (ad es. in un file di bootstrap) in modo che copra l'intera richiesta.
  6. Abbinalo a set_error_handler() e register_shutdown_function() per coprire anche avvisi, notifiche ed errori fatali.
  7. Usa restore_exception_handler() per ripristinare il gestore precedente quando uno personalizzato deve essere limitato a un blocco di codice.

Conclusione

set_exception_handler() ti fornisce un unico punto per gestire tutte le eccezioni non catturate in un'applicazione — trasformando un errore fatale grezzo in una registrazione consistente e un messaggio pulito per l'utente. Ricorda i suoi limiti: viene eseguito solo per le eccezioni non catturate, l'esecuzione si interrompe dopo, e il gestore stesso non deve mai lanciare eccezioni. Combinalo con set_error_handler() per gli avvisi, trigger-error per segnali di errore personalizzati e restore_exception_handler() per la gestione con ambito limitato, per costruire un sistema di segnalazione degli errori robusto.

Esercizio

Pratica
Cosa fa la funzione set_exception_handler() in PHP?
Cosa fa la funzione set_exception_handler() in PHP?
Was this page helpful?