Guida Completa alla Funzione mysqli_sqlstate in PHP
Scopri come mysqli_sqlstate() restituisce codici SQLSTATE ANSI/ISO in PHP, le differenze da mysqli_errno(), i codici più comuni e l'uso in modalità eccezione.
Quando si lavora con MySQL in PHP tramite l'estensione mysqli, è necessario un modo affidabile per scoprire perché una query è fallita. La funzione mysqli_sqlstate() restituisce il codice di errore SQLSTATE per l'operazione MySQL eseguita più di recente — un codice standardizzato e portabile che indica la categoria dell'errore.
Questa guida spiega cos'è SQLSTATE, in che modo mysqli_sqlstate() differisce dalla funzione MySQL-specifica mysqli_errno(), i codici che si incontrano più spesso e come utilizzarla correttamente (anche nella moderna modalità basata su eccezioni di PHP).
Cos'è SQLSTATE?
SQLSTATE è un codice di errore a cinque caratteri definito dallo standard ANSI/ISO SQL. Poiché fa parte dello standard e non è un'invenzione di MySQL, lo stesso codice ha un significato pressoché identico su diversi motori di database, rendendolo più portabile dei numeri di errore specifici del fornitore.
I cinque caratteri sono divisi in due parti:
- I primi due caratteri rappresentano la classe dell'errore. Ad esempio, la classe
00indica successo,01indica un avviso e42indica una violazione di sintassi o di regola di accesso. - Gli ultimi tre caratteri rappresentano la sottoclasse, che circoscrive ulteriormente il problema.
Quindi 42S02 ("base table or view not found") appartiene alla classe 42 (violazione di sintassi/accesso) con sottoclasse S02.
Sintassi
mysqli_sqlstate(mysqli $connection): stringmysqli_sqlstate() accetta un singolo argomento — l'oggetto connessione restituito da mysqli_connect() — e restituisce una string:
- Una string vuota ma riempita di zeri
"00000"quando l'ultima operazione è riuscita. - Un codice a cinque caratteri come
"42S02"quando si è verificato un errore.
Nello stile orientato agli oggetti questo è il metodo
$connection->sqlstate.
SQLSTATE vs. mysqli_errno: quale usare?
Queste due funzioni rispondono a domande diverse e spesso si vogliono entrambe:
| Funzione | Restituisce | Natura |
|---|---|---|
mysqli_sqlstate() | Una string a 5 caratteri come "42S02" | Standard ANSI/ISO — portabile tra database |
mysqli_errno() | Un intero come 1146 | Specifico di MySQL — più granulare, ma non portabile |
mysqli_error() | Un messaggio leggibile | Il testo descrittivo per la registrazione e il debug |
Regola generale: usa mysqli_sqlstate() nella logica di branching quando vuoi un codice che sopravviva a una migrazione del database, e ricorri a mysqli_errno() quando hai bisogno di una distinzione specifica di MySQL. Usa mysqli_error() per il messaggio da registrare.
Un esempio completo
Lo snippet qui sotto si connette, esegue una query su una tabella inesistente e stampa tutti e tre i dati diagnostici in modo da vedere come si correlano:
<?php
$connection = mysqli_connect('localhost', 'user', 'password', 'mydatabase');
if (!$connection) {
die('Connection failed: ' . mysqli_connect_error());
}
$sql = "SELECT * FROM table_that_does_not_exist";
if (mysqli_query($connection, $sql)) {
echo "Query executed successfully.";
} else {
echo "SQLSTATE: " . mysqli_sqlstate($connection) . "\n";
echo "Errno: " . mysqli_errno($connection) . "\n";
echo "Message: " . mysqli_error($connection) . "\n";
}
// Typical output:
// SQLSTATE: 42S02
// Errno: 1146
// Message: Table 'mydatabase.table_that_does_not_exist' doesn't existNota come lo SQLSTATE portabile (42S02) e il numero di errore specifico di MySQL (1146) descrivano lo stesso problema a due livelli di dettaglio.
Codici SQLSTATE più comuni
Questi sono i codici che più probabilmente si gestiscono nel lavoro quotidiano con PHP/MySQL:
| SQLSTATE | Significato |
|---|---|
00000 | Successo — nessun errore |
23000 | Violazione di vincolo di integrità (es. chiave duplicata, errore di chiave esterna) |
42000 | Errore di sintassi o violazione di regola di accesso |
42S02 | Tabella o vista di base non trovata |
42S22 | Colonna non trovata |
HY000 | Errore generico (quando non si applica nessun codice specifico) |
08S01 | Errore di comunicazione / collegamento di connessione |
La ramificazione su questi codici permette di reagire in modo significativo — ad esempio, trattare un errore di chiave duplicata 23000 come "questo record esiste già" invece di un errore fatale:
<?php
$sql = "INSERT INTO users (email) VALUES ('[email protected]')";
if (!mysqli_query($connection, $sql)) {
if (mysqli_sqlstate($connection) === '23000') {
echo "That email address is already registered.";
} else {
echo "Unexpected database error: " . mysqli_error($connection);
}
}Utilizzo con la modalità eccezione
Il moderno PHP (8.1+) abilita la segnalazione degli errori MySQL per impostazione predefinita, quindi una query fallita genera un'eccezione mysqli_sql_exception anziché restituire false. In quella modalità si legge lo SQLSTATE dal metodo getSqlState() dell'eccezione invece di chiamare mysqli_sqlstate() dopo il fatto:
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
$connection = mysqli_connect('localhost', 'user', 'password', 'mydatabase');
mysqli_query($connection, "SELECT * FROM missing_table");
} catch (mysqli_sql_exception $e) {
echo "SQLSTATE: " . $e->getSqlState() . "\n"; // e.g. 42S02
echo "Code: " . $e->getCode() . "\n"; // e.g. 1146
echo "Message: " . $e->getMessage();
}Se si chiama
mysqli_sqlstate()direttamente dopo che un'eccezione è già stata catturata, funziona comunque — ma all'interno di un bloccotry/catch, leggere il codice dall'oggetto eccezione è più pulito ed evita di interrogare nuovamente lo stato della connessione.
Considerazioni importanti
- Riflette solo l'ultima operazione. Ogni nuova query sovrascrive lo SQLSTATE precedente. Leggilo immediatamente dopo la chiamata che interessa — prima di eseguire qualsiasi altra cosa sulla stessa connessione.
"00000"è successo, non un errore. Non trattare un valore non vuoto come un errore; un'operazione riuscita restituisce la string di tutti zeri, non"".- Una connessione fallita non ha SQLSTATE. Se
mysqli_connect()stesso fallisce non esiste alcun oggetto connessione da interrogare, quindi usamysqli_connect_error()per i problemi di connessione.
Conclusione
mysqli_sqlstate() fornisce il codice SQLSTATE portabile e basato su standard per l'ultima operazione MySQL, complementando la funzione MySQL-specifica mysqli_errno() e il messaggio leggibile di mysqli_error(). Usa SQLSTATE nella logica di branching quando vuoi una gestione degli errori indipendente dal database, passa al metodo getSqlState() dell'eccezione quando lavori nella modalità eccezione predefinita di PHP e leggi sempre il codice subito dopo l'operazione che descrive.