PHP – Gestione delle Eccezioni

4 Lug

Out Of Date Warning

Questo post è stato pubblicato più di 2 anni fa (il 4 luglio 2011). Le idee vanno avanti velocemente, le prospettive cambiano quindi i contenuti potrebbero non essere aggiornati. Ti prego di tenere in considerazione questo, e di verificare le informazioni tecniche presenti nell'articolo prima di farne affidamento per i tuoi scopi.

Le eccezioni forniscono un meccanismo unificato per la gestione degli errori in modo estensibile, manutenibile, ed object-oriented.
L’idea di base è che il codice è eseguito all’interno di un blocco try, con un codice simile al seguente:

 

Se qualcosa va storto all’interno del blocco try, si può creare quella che viene chiamata un’eccezione.
Alcuni linguaggi, come Java, generano in certi casi, automaticamente delle eccezioni per noi.
In PHP, le eccezioni devono essere generate manualmente. Si genera un’eccezione come segue:

 

 

La parola chiave throw innesca il meccanismo di gestione delle eccezioni. Si tratta di un costrutto del linguaggio piuttosto che di una funzione.
Si aspetta di ricevere un oggetto. Nel caso più semplice, è possibile creare un’istanza della classe interna Exception, come fatto nell’esempio.
Il costruttore della classe prende 2 parametri, un messaggio ed un codice che sarebbero rispettivamente il messaggio ed il codice di errore. Entrambi i parametri sono opzionali.
Infine, sotto il tuo blocco try, è necessario almeno un blocco catch.
Un blocco catch assomiglia a questo:

 

L’oggetto passato al blocco catch è quello passato all’istruzione throw che ha generato l’eccezione.
L’eccezione può essere di qualsiasi tipo, ma è buona norma utilizzare le istanze della classe Exception o casi di eccezioni personalizzate definite dall’utente che ereditano dalla classe Exception.
Quando viene sollevata un’eccezione, PHP cerca un blocco catch corrispondente. Se si dispone di più di un blocco catch, gli oggetti passati a ciascuno dovrebbero essere di tipi diversi in modo che PHP può capire quale blocco catch usare.
Un altro punto da notare è che si può sollevare ulteriori eccezioni all’interno di un blocco catch.

Un semplice esempio di gestione delle eccezioni:

 

 

La classe Exception

Come discusso prima il costruttore della classe Exception accetta 2 parametri, il messaggio ed il codice di errore.
In aggiunta al costruttore la classe ha i seguenti metodi:

  • getCode() ->Ritorna il codice passato al costruttore
  • getMessage() -> Ritorna il messaggio passato al costruttore
  • getFile -> Ritorna il full path del file in cui l’eccezione è stata sollevata
  • getLine -> Ritorna il numero di linea in cui l’eccezione viene sollevata
  • getTrace -> Ritorna un array contenente un backtrace dove l’eccezione è stata sollevata
  • getTraceAsString -> Ritorna le stesse info di getTrace formattate come stringa
  • __toString -> Permette di fare un’echo di un oggetto Exception, dando tutte le info dei metodi di sopra. es: echo $e

PS: backtrace mostra quali funzioni erano in esecuzione al momento del sollevamento dell’eccezione.

Eccezioni definite dall’utente

Invece di istanziare e passare un’istanza della classe Exception di base, possiamo passare un oggetto simile.
In molti casi estenderemo la classe Exception per crearne una personalizzata.
Il manuale di PHP fornisce uno scheletro della classe Exception attraverso il quale possiamo capire come estenderla.
Si noti che questo non è il codice vero e proprio ma rappresenta ciò che ci si può aspettare di ereditare:

 

 

Da notare che la maggior parte dei metodi pubblici sono final. Ciò significa che non possono essere sovrascritti.

È possibile creare sottoclassi, ma non è possibile modificare il comportamento dei metodi di base. Notare che invece è possibile eseguire l’override della funzione __toString().
È inoltre possibile aggiungere dei metodi personali. Vediamo un esempio in cui vado e crearmi la mia funzione _toString personalizzata:

 

 

Potrò poi tranquillamente usare la mia nuova classe quando voglio generare un’eccezione così:

 

 

Vediamo infine un esempio di implementazione in cui definisco tre sottoclassi diverse di Exception, all’interno di un blocco try andrò a generare eccezioni diverse in base all’errore. E’ più semplice intuire il funzionamento leggendo il codice che a parole.
Poniamo che le tre classi che estendono Exception (di cui non sto a scrivere il codice) siano miaException1, miaException2 e miaException2:

 

Da notare infine che ho creato due (invece che tre) cath diversi che vengono eseguiti in base all’oggetto passato.
Se è di tipo miaException1 allora sarà eseguito il primo, mentre negli altri casi il secondo, visto che tutte le classi ereditano da Exception.

2 Commenti su “PHP – Gestione delle Eccezioni”

  1. Simone 5 maggio 2014 at 15:44 #

    Ciao, c’è una cosa che non ho capito di questo argomento e che nessun blog/sito spiega.

    In un contesto di programmazione OOP, il blocco try/catch va posto nel metodo o nell’implementazione dello stesso?

    Grazie mille!

    • grimax 5 maggio 2014 at 16:06 #

      No so se ho capito bene la domanda ma direi che la soluzione più logica è lanciare l’eccezione nella dichiarazione del metodo e quindi il try/catch al di fuori, ovvero nel client che chiama il metodo.
      Quindi in un’ipotetica applicazione MVC eccezione nel modello e try/catch sul controller.

Lascia un commento