98 Try e Catch – Le eccezioni

Le eccezioni sono un’anomalia rispetto al normale flusso che, una volta sollevata, può essere catturata.
Già dalla versione 5 di php esisteva la classe Exception che se veniva estesa permetteva la creazione di regole particolari che potevamo costruire.
Da php 7 la classe Exception deve essere estesa tramite l’interfaccia di base Throwable presente di default in php. Per dettagli e i metodi dell’interfaccia rimando alla guida ufficiale. Per estendere la classe Exception si utilizza la keyword throw che significa lancia :

throw new Exception('non esiste');

Questo comando significa lancia una nuova eccezione e il parametro passato alla classe  Exception è il messaggio.

Possiamo anche passare come secondo parametro un codice di errore per eventualmente fornire un riferimento sul codice che genera l’errore

throw new Exception('non esiste', -15);

creiamo una classe con un metodo che stampa il valore di una proprietà

class pippo {
    public $prop = 'hola';

    public function funz($p) {
            echo $this->prop = $p;
     
    }
}

facciamo un controllo se viene passato un valore inferiore  a 10 stampiamo il valore oppure solleviamo un eccezione se è maggiore di 10

class pippo {
    public $prop = 'hola';

    public function funz($p) {
        if ($p < 10) {
            echo $this->prop = $p;
        } else {
                 throw new Exception('NON ESISTE NULLA', -15);
               }
    }
}

se adesso lanciamo il metodo creando l’oggetto senza passare valore, otterremo l’errore

$a = new pippo();
$a->funz();

try catch

adesso invece di eseguire il metodo, cerchiamo di eseguirlo, tramile l’istruzione try { }

try {
    $a = new pippo();
    $a->funz('p');
}

stiamo dicendo prova ad eseguire il metodo funz passando la stringa ‘p’ come parametro.

Ci manca adesso la parte dove catturiamo l’eccezione tramite il blocco catch()

try {
    $a = new pippo();
    $a->funz('p');
} catch () {

}

Il blocco catch riceve di default da php un oggetto passato come parametro a cui daremo un nome a nostro piacere che per convenzione spesso viene chiamato $e (iniziale di error). Questo oggetto potrà essere di diversi tipi, quello più utilizzato è un oggetto di tipo Exception

catch (Exception $e) { }

a questo punto all’interno del blocco catch restituiremo l’errore catturato definito nel lancio dell’eccezione usufruendo del metodo predefinito getMessage() della classe Exception

catch (Exception $e) {
    echo $e->getMessage();
}

La classe Exception ha diversi metodi consultabili qui, per esempio possiamo anche far restituire il codice di errore grazie al metodo getcode() 

catch (Exception $e) {
    echo $e->getMessage();
    echo $e->getCode();
}

ecco il codice completo

class pippo {
    public $prop = 'hola';

    public function funz($p) {
        if ($p<10) {
            echo $this->prop = $p;
        }  else {
                  throw new Exception('NON ESISTE NULLA', -15);
                 }
    }
}

try {
    $a = new pippo();
    $a->funz(11);
} catch (Exception $e) {
    echo $e->getMessage();
    echo $e->getCode();
}

Finally

Abbiamo visto che il blocco try / catch prova ad eseguire delle istruzioni nella parte try che se funzionano vengono eseguite, altrimenti viene catturata un eccezione e vengono eseguite delle azioni di loggin nel blocco catch. Si può chiudere il blocco con l’aggiunta del , costrutto finally che comunque viene sempre eseguito, indipendentemente dall’esito

try {
    $a = new pippo();
    $a->funz(1);
} catch (Exception $e) {
    echo $e->getMessage();
    echo $e->getCode();
} finally {
    echo 'codice finito';
}