back to top

PHP try e catch โ€“ Gestione delle eccezioni in PHP

Nello scripting server side in PHP, gli errori possono gestiti tramite eccezioni. Questo approccio, che i programmatori in Java o C++ conosceranno giร  molto bene, consente di separare nettamente, giร  in fase di sviluppo, la gestione degli errori dalla logica dellโ€™applicativo.

Dato che nella programmazione, gli errori sono inevitabili, diviene necessario creare degli accorgimenti che limitino il piรน possibile le perdite di tempo legate alla ricerca dei frammenti di codice errati velocizzando, contestualmente, la loro risoluzione.

Pubblicitร 

Fino alla versione 4 di PHP, purtroppo, non cโ€™era molto da fare: si scriveva il codice e poi lo si testava, gli errori โ€œvenivano fuoriโ€ e si andava alla ricerca della riga affetta dallโ€™errore per poi applicare la soluzione adeguata.

Exception Handling in PHP

Con PHP 5, per fortuna, sono stati introdotti alcuni nuovi strumenti per lโ€™analisi del nostro codice e per la razionalizzazione dei tempi di intervento a carico delle istruzioni mal digitate.

La logica che stร  alla base dellโ€™Exception Handling in PHP prende il nome di try (prova), throw (lancia) e catch (cattura), per cui il controllo delle eccezioni emula in parte lโ€™azione svolta dalle istruzioni di controllo o condizionali come if ed else.

Se per esempio salviamo il seguente codice in una pagina chiamata eccezione.php, e lo lanciamo:

<?
throw new Exception('Errore!!!!!!!!');
?>

prevedibilmente, il risultato ottenuto sarร  simile allโ€™output riportato qui di seguito:

Fatal error: Uncaught exception 'Exception' 
with message 'Errore!!!!!!!!' 
in c:\programmi\php\www\error.php:2 Stack trace: #0 {main} 
thrown in c:\programmi\php\www\error.php on line 2

Al lancio dello โ€œscriptinoโ€ abbiamo due effetti: il primo รจ la notifica di un Uncaught exception (letteralmente: โ€œeccezione non catturataโ€), il secondo, ben piรน importante ai fini dellโ€™Exception Handling, รจ il fatto che a seguito di questa notifica il resto delle istruzioni contenute nel codice, se presenti, non verranno eseguite.

In pratica, in questo caso lโ€™effetto di unโ€™azione di throwning sul codice PHP puรฒ essere paragonato a quello di una clausola die() che blocca lโ€™esecuzione del listato a seguito di un controllo.

Try, throw e catch delle eccezioni in PHP

Lโ€™azione di controllo svolta dalla logica del try, throw e catch prevede quindi due esiti possibili:

  • o lโ€™eccezione viene rilevata (catching con esito positivo) e quindi le istruzioni previste nel listato successivo allโ€™errore non vengono escluse dal ciclo di esecuzione stabilito dal sorgente;
  • oppure, lโ€™eccezione non viene rilevata (Uncaught exception) e quindi i possibili input previsti vengono abortiti e non producono effetti (o, per meglio dire, non vengono prodotti come effetto).

Per eseguire efficacemente il catching di unโ€™eccezzione รจ possibile racchiudere il codice destinato allโ€™esecuzione allโ€™interno di un blocco in cui รจ prevista la prova e il lancio del listato (un cosiddetto blocco try and catch). Allโ€™interno di questo blocco di istruzioni potremo operare una distinzione efficace tra codice privo di errori e codice in grado di produrre notifiche di errore.

Allo scopo di chiarire meglio quanto appena espresso, un esempio pratico puรฒ essere di grande aiuto:

<?
try {    
  print "Stampa questo codice.";   
  throw new Exception('<br />Contollo delle eccezioni.');
  print "Blocca tutto!!";
} 
catch(Exception $var) {
  print $var->getMessage();
}
?>

Salviamo il codice appena proposto in una pagina chiamata, ad esempio, eccezione2.php ed eseguiamola. Cosรฌ facendo riceveremo in output la stampa a video delle seguenti stringhe:

Stampa questo codice.
Contollo delle eccezioni.

Cosa รจ accaduto? apparentemente non molto, ma in relatร  il nostro listato ha eseguito tutta una serie di operazioni che, naturalmente, evidenziano nellโ€™output solo il loro risultato finale.

Innazitutto la prima stringa destinata alla stampa a video (โ€œStampa questo codice.โ€) non viene sottoposta a controlli nรจ produce eccezioni, ma rientra comunque nel blocco di try; lโ€™istruzione ad essa correlata verrร  eseguita correttamente.

In secondo luogo viene lanciata unโ€™eccezione seguendo la stessa procedura utilizzata nellโ€™esempio precedente. Lโ€™eccezione non รจ stata ancora sottoposta ad unโ€™azione di catching e quindi lโ€™istruzione immediatamente sottostante, la stampa a video della stringa โ€œBlocca tutto!!โ€ non viene eseguita.

Viene effettuato il catching dellโ€™eccezione e lโ€™effetto conseguente al lancio di questโ€™ultima viene passato come valore ad una variabile ($var).

Infine, il metodo getMessage() raccoglie la variabile prodotta dallโ€™azione di catching accettandola come parametro e viene stampata a video la stringa che le รจ stata assegnata come valore.

Try e catch con notifica dellโ€™eccezione

Nel precedente paragrafo abbiamo descritto un primo esempio riguardante la possibilitร  di creare un try and catch block allโ€™interno del quale testare gli output derivanti dal sistema di controllo denominato try, throw e catch.

Lโ€™esempio precedente non prevede di visualizzare le notifiche di errore al presentarsi di unโ€™eccezione, quindi ora presenteremo del codice destinato ad una funzione esattamente contraria. Salviamo il listato esposto qui sotto in un file chiamato, ad esempio, eccezione3.php:

<?
try {
  $n1 = -1000;
  $n2 = -2; 
  if ( $n1 < $b2 )
  {
    throw new Exception($n1 . " รจ inferiore a " . $n2 . "<br />");
    echo "Prova a stamparmi se ci riesci!";
  }
}
catch (Exception $excp) {
  echo "Alt!! Ho trovato un'eccezione:<br />", $excp;
}
?>

Di seguito, riportiamo per completezza espositiva la stampa a video dellโ€™output conseguente al test del codice appena digitato:

Alt!! Ho trovato un'eccezione:
exception 'Exception' with message '-1000 รจ inferiore a -2
' in c:\programmi\php\www\err.php:7 Stack trace: #0 {main}

Lo script proposto ci riporta a quanto detto allโ€™inizio di questo articolo circa quanto accadeva sino a PHP 4: il limite insito in un sistema come quello stava nellโ€™impossibilitร  di poter โ€œspecializzareโ€ le operazioni di Exception Handling predefinendo la tipologia di reazione a seconda delle differenti possibilitร  di errore.

Nel codice proposto nellโ€™esempio qui sopra abbiamo innanzitutto sottoposto delle istruzioni a try; di seguito abbiamo lanciato, allโ€™interno del blocco try, unโ€™eccezione tramite throw e questo ha determinato lโ€™impossibilitร  di eseguire le ulteriori istruzioni poste allโ€™interno dello stesso blocco try.

Lโ€™eccezione รจ stata quindi istanziata quale oggetto appartenente alla classe precedentemente definita, cioรจ Exception. Lโ€™istanza, conferendo delle proprietร  allโ€™oggetto lo ha reso riutilizzabile, infatti, lo ritroviamo al di fuori del blocco di try dove diviene argomento di unโ€™istruzione e non ne blocca lโ€™esecuzione.

Variabili e metodi per le eccezioni in PHP

In questo articolo descriveremo le variabili e i metodi che entrano in gioco nelle azioni di Exception Handling, entrambi sono elementi costitutivi รจ nativi della classe Exception, vera protagonista della gestione degli errori tramite eccezioni.

La variabili

Per quanto riguarda le variabili, vanno presi in considerazione essenzialmente tre voci:

  • Exception :: message: il messaggio di errore che verrร  passato come argomento al costruttore della classe.
  • Exception :: line: il punto esatto del blocco di codice in cui viene generato lโ€™errore.
  • Exception :: file:il nome del file PHP in cui a origine lโ€™errore gestito tramite eccezione.

Le tre variabili appena descritte sono โ€œprotetteโ€, non potranno quindi essere riscritte e ogni tentativo di modifica a loro carico non farร  altro che generare la notifica di un errore.

I metodi

Passiamo ora ai metodi. Questi ultimi sono pubblici e quindi accessibili in tutto il contesto appartenente alla classe in cui viene istanziato lโ€™oggetto. Per la precisione possiamo distinguere 5 diversi metodi:

  • Exception :: getMessage(): lo abbiamo descritto in precedenza; esso รจ destinato a raccogliere come parametro la notifica di errore che viene generata dal controllo delle eccezioni. In pratica reinvia il messagio di errore come parametro al costruttore della classe di riferimento.
  • Exception :: getLine(): รจ il metodo che permette il reinvio alla riga di codice in cui si verifica lโ€™errore.
  • Exception :: getTrace(): metodo che reinvia ad una tabella associtiva riguardante le caratteristiche dellโ€™errore.
  • Exception :: getTraceAsString(): metodo che svolge una funzione similare allโ€™Exception :: getTrace() ma crea una stringa con lo stesso contenuto di informazioni.

Il metodo Exception :: getTrace()

Exception :: getTrace() si presenta come il metodo piรน complesso in quanto contiene differenti tipi di informazioni riguardanti lโ€™entitร  dellโ€™errore gestito. Allโ€™interno di questโ€™ultimo metodo rileviamo 6 differenti elementi costitutivi che potremo riassumere nellโ€™elenco seguente:

  • file: il documento in cui si verifica lโ€™errore.
  • line: la riga di codice in cui si verifica lโ€™errore.
  • function: la funzione coinvolta nellโ€™errore.
  • class: la classe coinvolta nellโ€™errore.
  • type: il modo in cui viene richiamato il metodo che potrebbe essere statico o dinamico.
  • args: gli argomenti passati al metodo raccolti in una tabella associativa.

Una classe per la gestione delle eccezioni

Dopo la nostra breve discussione sulle dinamiche e le procedure da adottare per la gestione degli errori tramite eccezioni in PHP 5, cercheremo di chiarire definitivamente le idee al lettore presentandogli un esempio pratico riguardante lโ€™utilizzo del sistema try, throw e catch.

Nello specifico creeremo una classe da poter impiegare in unโ€™operazione abbastanza frequente nello sviluppo di applicazioni in PHP: una funzione per lโ€™apertura di un file in lettura.

Chiameremo la nostra funzione personalizzata ApriScatole(), mentre la classe di appartenenza prenderร  il nome di provaEccezione. Di seguito riportiamo il listato completo di funzione e utilizzo pratico della stessa:

<?
//definizione della classe
class provaEccezione {

  //creiamo la funzione 
  public function ApriScatole($file) {
    if(!@fopen($file, 'r')) 
    {
      //stabiliamo le modalitร  di gestione dell'errore
      throw new Exception ('Il ' . $file . 'non si apre!!!');
    }
  }
}

//istanza
$obj = new provaEccezione;

//tentiamo di aprire un file inesistente
try {
  $obj -> ApriScatole('/percorso/file_inesistente.txt');
  //se il file esiste stampo a video una conferma
  echo 'Ho aperto il file!';
} 

//cathing dell'eccezione
catch (Exception $excp) {
  echo $excp -> getMessage();
}
?>

Basterร  il semplice test dello script appena presentato per osservare gli effetti della gestione dellโ€™errore.

In pratica non abbiamo fatto altro che definire una classe allโ€™interno della quale รจ stata creata una funzione che controlla lโ€™effettiva apertura in lettura di un file. Se il file passato come argomento non viene aperto, allora lโ€™errore viene gestito secondo le modalitร  previste nella fase di throw.

Per testare la funzione abbiamo proceduto con lโ€™istanza di un oggetto nel tentativo di aprire un file inesistente utilizzando la funzione appena creata, ma lโ€™operazione porterร  logicamente ad un errore la cui notifica verrร  raccolta tramite catch e visualizzata tramite il metodo getMessage().

Altri contenuti interessanti

Pubblicitร 

Potrebbero interessarti queste guide

Claudio Garau
Claudio Garau
Web developer, programmatore, Database Administrator, Linux Admin, docente e copywriter specializzato in contenuti sulle tecnologie orientate a Web, mobile, Cybersecurity e Digital Marketing per sviluppatori, PA e imprese.

Leggi anche...

Cannot modify header information โ€“ headers already sent: come risolvere lโ€™errore PHP

L'errore di PHP cannot modify header information - headers...

Ricavare lโ€™estensione di un file con PHP

Quando si lavora con i file in un'applicazione web,...

GD Library: creazione, manipolazione e ridimensionamento immagini con PHP

Le librerie GD (o GD Library), sono componenti fondamentali...

PHP: impostare il fuso orario italiano

Le tue pagine PHP non mostrano lโ€™orario corretto? Probabilmente...

PHP BBCode: script pronti allโ€™uso

A volte puรฒ aversi l'esigenza di dover offrire agli...
Pubblicitร