Nell’articolo introduttivo alla classe mysqli (link), per semplicità di trattazione non si è preso in considerazione il problema del controllo degli errori che possono verificarsi nel corso dell’esecuzione degli script PHP e che possono determinare la comparsa nella pagina di messaggi di errore incomprensibili all’utente, come quelli mostrati nella figura seguente.
Gli errori della figura precedente sono stati determinati dall’esecuzione del seguente script di esempio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<!DOCTYPE html> <html> <head> <title>Gestione errori</title> </head> <body> <?php //si connette al server MySQL $conn = new mysqli("localhoste", "root", ""); //crea il database se non esiste $query = "CREATE DATABASE IF NOT EXISTS clienti;"; $conn->query($query); //si connette al database 'clienti' $conn->select_db('clienti'); //crea la tabella anagrafica $query = "CREATE TABLE IF NOT EXISTS anagrafica ( idCliente INT(10) NOT NULL AUTO_INCREMENT, cognome VARCHAR(30) NOT NULL, nome VARCHAR(30) NOT NULL, residenza VARCHAR(30), PRIMARY KEY(idCliente) ) CHARACTER SET utf8 COLLATE utf8_general_ci;"; $conn->query($query); //popola la tabella con alcuni dati di prova $query = "INSERT INTO anagrafica (cognome, nome, residenza) VALUES ('Rossi', 'Mario', 'Milano'), ('Bianchi', 'Laura', 'Torino'), ('Verdi', 'Antonio', 'Genova'), ('Viola', 'Amanda', 'Potenza'), ('Arancio', 'Gloria', 'Potenza');"; $conn->query($query); //visualizza i record dei clienti di Potenza $query = "SELECT * FROM anagrafica WHERE residenza = 'Potenza'"; $ris = $conn->query($query); echo "<table>"; echo "<th>id</th> <th>Cognome</th> <th>Nome</th> <th>Residenza</th>"; while ($riga = $ris->fetch_assoc()) { echo "<tr>"; echo "<td>$riga[idCliente]</td>"; echo "<td>$riga[cognome]</td>"; echo "<td>$riga[nome]</td>"; echo "<td>$riga[residenza]</td>"; echo "</tr>"; } echo "</table>"; //chiude la connessione $conn->close(); ?> </body> </html> |
Nello script precedente volutamente è stato introdotto un errore: il nome corretto dell’host del server MySQL con cui stabilire la connessione doveva essere ‘localhost‘ e non ‘localhoste‘! A causa di questo errore la connessione con il server MySQL non viene stabilita e ciò determina una serie di errori a catena. Una situazione analoga a questa può aversi se, nonostante la correttezza dello script, per qualche ragione il server non è disponibile.
Le funzioni exit() e die()
In generale in uno script PHP gli errori che possono scaturire dall’esecuzione di un’istruzione che interagisce con il server, possono determinare una situazione non recuperabile che può compromettere la corretta esecuzione delle istruzioni successive. Pertanto, per tali istruzioni è necessario verificare la loro corretta esecuzione e definire, in caso contrario, un comportamento alternativo che, nella maggior parte dei casi, consiste nella terminazione dello script PHP e nella visualizzazione di un messaggio opportuno. A tale scopo si utilizzano le funzioni exit() o die(), così come mostrato di seguito:
1 2 3 4 5 6 |
//si connette al server MySQL $conn = @ new mysqli("localhost", "root", ""); if ($conn->connect_error) die("Errore: impossibile stabilire la connessione con il server."); /*oppure exit("Errore: impossibile stabilire la connessione con il server.");*/ |
Nel codice precedente, dopo l’istruzione che tenta di stabilire una connessione al server MySQL, con la if() si controlla se essa abbia determinato un errore, nel qual caso lo script viene interrotto richiamando la funzione die() e nella pagina viene visualizzato il messaggio di errore passato come stringa alla funzione. Come condizione di controllo della struttura if() è stato utilizzato l’attributo connect_error dell’oggetto di classe mysqli, che: nel caso di errore, è una stringa con la descrizione dell’errore (che viene interpretata dalla if() come true), nel caso contrario una stringa vuota (che viene interpretata dalla if() come false).
L’operatore ‘@’ di controllo degli errori
Nel codice precedente è stato utilizzato anche l’operatore ‘@’, detto operatore di controllo degli errori del linguaggio PHP. Questo operatore può essere anteposto all’istruzione che si sta controllando, per impedire la visualizzazione del messaggio di warning dell’errore da essa generato. La figura seguente mostra il risultato dell’esecuzione dello script precedente con la modifica proposta.
Ovviamente il controllo dell’errore che è stato realizzato sull’istruzione che stabilisce la connessione con il server, andrebbe fatto anche sulle altre istruzioni che fanno interagire lo script PHP con il server, così come viene mostrato di seguito.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
<!DOCTYPE html> <html> <head> <title>Gestione errori</title> </head> <body> <?php //si connette al server MySQL $conn = @ new mysqli("localhost", "root", ""); if ($conn->connect_error) die("Errore: impossibile stabilire la connessione con il server."); //crea il database se non esiste $query = "CREATE DATABASE IF NOT EXISTS clienti"; if(@ $conn->query($query)) echo "Database clienti ok.<br/>"; else { $conn->close(); die("Errore, si sono vericafati dei problemi con il database 'clienti'.<br/>"); } //si connette al database 'clienti' if(@ $conn->select_db('clienti')) echo "Connessione al database 'clienti' riuscita.<br/>"; else { @ $conn->close(); die("Errore nella connessione al database 'clienti'.<br/>"); } //crea la tabella anagrafica $query = "CREATE TABLE IF NOT EXISTS anagrafica ( idCliente INT(10) NOT NULL AUTO_INCREMENT, cognome VARCHAR(30) NOT NULL, nome VARCHAR(30) NOT NULL, residenza VARCHAR(30), PRIMARY KEY(idCliente) ) CHARACTER SET utf8 COLLATE utf8_general_ci;"; if(@ $conn->query($query)) echo "Tabella 'anagrafica' ok.<br/>"; else { @ $conn->close(); die("Errore nella creazione della tabella 'anagrafica'.<br/>"); } //popola la tabella con alcuni dati di prova $query = "INSERT INTO anagrafica (cognome, nome, residenza) VALUES ('Rossi', 'Mario', 'Milano'), ('Bianchi', 'Laura', 'Torino'), ('Verdi', 'Antonio', 'Genova'), ('Viola', 'Amanda', 'Potenza'), ('Arancio', 'Gloria', 'Potenza');"; if(@ $conn->query($query)) echo "Record inseriti correttamente.<br/>"; else die("Errore nell'inserimento dei record.<br/>"); //visualizza i record dei clienti di Potenza $query = "SELECT * FROM anagrafica WHERE residenza = 'Potenza'"; $ris = @ $conn->query($query); if ($conn->errno) { @ $conn->close(); die("Errore, interrogazione non riuscita.<br/>"); } echo "Ok, interrogazione riuscita. Risultato:<br/>"; echo "<table>"; echo "<th>id</th> <th>Cognome</th> <th>Nome</th> <th>Residenza</th>"; while ($riga = $ris->fetch_assoc()) { echo "<tr>"; echo "<td>$riga[idCliente]</td>"; echo "<td>$riga[cognome]</td>"; echo "<td>$riga[nome]</td>"; echo "<td>$riga[residenza]</td>"; echo "</tr>"; } echo "</table>"; //chiude la connessione @ $conn->close(); ?> </body> </html> |
Nello script precedente rispetto a quanto già detto sopra, l’unica novità è l’aver utilizzato l’attributo errno dell’oggetto di classe msqli che contiene il numero dell’errore: esso è diverso da zero e, quindi, è interpretato dalla if come true, nel caso sia stato generato un errore, oppure in caso contrario vale zero e quindi è interpretato dalla if come false. Nella figura seguente viene mostrato ciò che lo script PHP visualizza nella pagina nel caso non si verifichi alcun errore.