
Durante lo sviluppo o l'esecuzione di un'applicazione PHP, possono verificarsi degli errori che compromettono il funzionamento del codice o la qualità del risultato. Per questo motivo, è importante gestire gli errori in maniera adeguata, sia per individuarli e correggerli, sia per prevenirli o mitigarne gli effetti. PHP offre due meccanismi principali per la gestione degli errori: la segnalazione degli errori e le eccezioni. Vediamo in cosa consistono e come si usano in PHP.
Gestione degli Errori
La segnalazione degli errori è il meccanismo che permette a PHP di comunicare al programmatore o all'utente la presenza di un errore nel codice. PHP ha diversi livelli di errori, che indicano la gravità o la natura dell'errore:
- Notice: sono errori di basso livello, che non influiscono sul funzionamento del codice, ma che segnalano delle situazioni potenzialmente problematiche, come l'uso di variabili non definite o l'accesso a indici non esistenti di un array.
- Warning: sono errori di medio livello, che non bloccano l'esecuzione del codice, ma che indicano delle situazioni che potrebbero causare dei risultati inaspettati o indesiderati, come l'apertura fallita di un file o la divisione per zero.
- Fatal Error: sono errori di alto livello, che interrompono l'esecuzione del codice, e che indicano delle situazioni che impediscono il normale funzionamento dell'applicazione, come la chiamata a una funzione non esistente o la mancanza di memoria. Per configurare la segnalazione degli errori, si possono usare due funzioni: `error_reporting()` e `ini_set()`. La funzione `
error_reporting()
` permette di impostare il livello di errori da segnalare, tramite una costante predefinita o una combinazione di costanti con l'operatore `|`.
<?php
// Segnala solo gli errori fatali
error_reporting(E_ERROR);
// Segnala tutti gli errori tranne le notice
error_reporting(E_ALL & ~E_NOTICE);
// Segnala tutti gli errori
error_reporting(E_ALL);
?>
La funzione ini_set()
permette di impostare il comportamento di PHP rispetto agli errori, tramite delle direttive di configurazione. Le principali direttive sono:
display_errors
: se impostata aOn
, mostra gli errori sullo schermo; se impostata aOff
, nasconde gli errori dallo schermo. Questa direttiva è utile per evitare di mostrare informazioni sensibili o inutili all’utente finale, e per facilitare il debug durante lo sviluppo.log_errors
: se impostata aOn
, registra gli errori in un file di log; se impostata aOff
, non registra gli errori in un file di log. Questa direttiva è utile per tenere traccia degli errori e per analizzarli successivamente.error_log
: specifica il percorso del file di log in cui registrare gli errori. Se non viene specificato, il file di log è quello predefinito del sistema operativo.
Ad esempio:
<?php
// Nasconde gli errori dallo schermo
ini_set('display_errors', 'Off');
// Registra gli errori in un file di log
ini_set('log_errors', 'On');
// Imposta il file di log personalizzato
ini_set('error_log', 'errori.log');
?>
Per gestire gli errori in maniera personalizzata, si può usare la funzione set_error_handler()
, che accetta come parametro il nome di una funzione definita dall’utente, che verrà invocata ogni volta che si verifica un errore. La funzione deve accettare almeno quattro parametri: il livello dell’errore, il messaggio dell’errore, il file in cui si è verificato l’errore e la linea in cui si è verificato l’errore. Ad esempio:
<?php
// Definisco la funzione per gestire gli errori
function gestisci_errori($livello, $messaggio, $file, $linea) {
// Mostro un messaggio personalizzato
echo "Si è verificato un errore: $messaggio<br>";
echo "Livello: $livello<br>";
echo "File: $file<br>";
echo "Linea: $linea<br>";
}
// Imposto la funzione come gestore degli errori
set_error_handler('gestisci_errori');
?>
Eccezioni
Le eccezioni sono un meccanismo che permette di gestire gli errori in maniera più controllata e strutturata. Le eccezioni sono degli oggetti che rappresentano delle situazioni eccezionali o anomale che si verificano durante l’esecuzione del codice. Le eccezioni possono essere generate da PHP o dal programmatore, e possono essere catturate e gestite tramite la struttura try-catch
.
La struttura try-catch
consiste di due blocchi di codice: il blocco try
, che contiene il codice potenzialmente soggetto a errori, e il blocco catch
, che contiene il codice da eseguire in caso di errore. Il blocco catch
accetta come parametro un’eccezione, che può essere usata per ottenere informazioni sull’errore. Ad esempio:
<?php
// Provo a eseguire un codice
try {
// Apro un file
$file = fopen('test.txt', 'r');
// Leggo il contenuto del file
$contenuto = fread($file, filesize('test.txt'));
// Chiudo il file
fclose($file);
// Mostro il contenuto del file
echo $contenuto;
}
// Catturo un'eccezione
catch (Exception $e) {
// Mostro un messaggio di errore
echo 'Si è verificato un errore: ' . $e->getMessage();
}
?>
Nell’esempio, se il file test.txt
non esiste o non è leggibile, si verifica un errore che genera un’eccezione. L’eccezione viene catturata dal blocco catch
, che mostra un messaggio di errore usando il metodo getMessage()
dell’eccezione. In questo modo, si evita che l’errore blocchi l’esecuzione del codice, e si può gestire l’errore in maniera appropriata.
Per generare un’eccezione personalizzata, si può usare la parola chiave throw
, seguita da un’istanza della classe Exception
o di una sua sottoclasse. La classe Exception
ha un costruttore che accetta due parametri: il messaggio dell’eccezione e il codice dell’eccezione. Ad esempio:
<?php
// Definisco una funzione che genera un'eccezione
function dividi($a, $b) {
// Controllo se il divisore è zero
if ($b == 0) {
// Genero un'eccezione
throw new Exception('Divisione per zero', 1);
}
// Restituisco il risultato della divisione
return $a / $b;
}
// Provo a chiamare la funzione
try {
// Chiamo la funzione con due numeri
$risultato = dividi(10, 0);
// Mostro il risultato
echo $risultato;
}
// Catturo un'eccezione
catch (Exception $e) {
// Mostro un messaggio di errore
echo 'Si è verificato un errore: ' . $e->getMessage();
}
?>
Nell’esempio, se si chiama la funzione dividi()
con il secondo parametro uguale a zero, si genera un’eccezione con il messaggio ‘Divisione per zero’ e il codice 1. L’eccezione viene catturata dal blocco catch
, che mostra il messaggio di errore.
Per creare un'eccezione personalizzata, si può estendere la classe `Exception` e definire dei propri attributi e metodi. Ad esempio:
<?php
// Definisco una classe per le eccezioni di divisione per zero
class DivisionePerZeroException extends Exception {
// Definisco un attributo per il divisore
private $divisore;
// Definisco un costruttore che accetta il divisore come parametro
public function __construct($divisore) {
// Invoco il costruttore della classe padre con un messaggio e un codice predefiniti
parent::__construct('Divisione per zero', 1);
// Assegno il valore del divisore all'attributo
$this->divisore = $divisore;
}
// Definisco un metodo per ottenere il divisore
public function getDivisore() {
return $this->divisore;
}
}
// Definisco una funzione che genera un'eccezione di divisione per zero
function dividi($a, $b) {
// Controllo se il divisore è zero
if ($b == 0) {
// Genero un'eccezione di divisione per zero
throw new DivisionePerZeroException($b);
}
// Restituisco il risultato della divisione
return $a / $b;
}
// Provo a chiamare la funzione
try {
// Chiamo la funzione con due numeri
$risultato = dividi(10, 0);
// Mostro il risultato
echo $risultato;
}
// Catturo un'eccezione di divisione per zero
catch (DivisionePerZeroException $e) {
// Mostro un messaggio di errore
echo 'Si è verificato un errore: ' . $e->getMessage();
// Mostro il divisore
echo 'Divisore: ' . $e->getDivisore();
}
?>
Nell’esempio, si definisce una classe DivisionePerZeroException
che estende la classe Exception
e che ha un attributo divisore
e un metodo getDivisore()
. Si genera un’eccezione di questa classe nella funzione dividi()
se il divisore è zero, e si cattura l’eccezione nel blocco catch
, mostrando il messaggio e il divisore.
Per eseguire del codice indipendentemente dal risultato del blocco try-catch
, si può usare il blocco finally
, che viene eseguito dopo il blocco try
o il blocco catch
, a prescindere dal fatto che si sia verificata un’eccezione o meno. Il blocco finally
è utile per rilasciare delle risorse o eseguire delle operazioni di pulizia. Ad esempio:
<?php
// Provo a eseguire un codice
try {
// Apro un file
$file = fopen('test.txt', 'r');
// Leggo il contenuto del file
$contenuto = fread($file, filesize('test.txt'));
// Mostro il contenuto del file
echo $contenuto;
}
// Catturo un'eccezione
catch (Exception $e) {
// Mostro un messaggio di errore
echo 'Si è verificato un errore: ' . $e->getMessage();
}
// Eseguo del codice in ogni caso
finally {
// Chiudo il file se è aperto
if (isset($file)) {
fclose($file);
}
}
?>
Nell’esempio, si usa il blocco finally
per chiudere il file se è stato aperto, indipendentemente dal fatto che si sia verificato un errore o meno.
Conclusione
In conclusione, la gestione degli errori e delle eccezioni è un aspetto fondamentale dello sviluppo di applicazioni web in PHP. La segnalazione degli errori permette di comunicare la presenza di un errore nel codice, e di configurare il livello e il comportamento degli errori. Le eccezioni permettono di gestire gli errori in maniera più controllata e strutturata, tramite la struttura try-catch
e la parola chiave throw
. Per scegliere il meccanismo più adatto, bisogna valutare il tipo di errore, il livello di controllo e la qualità del codice.