W3docs

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 00 indica successo, 01 indica un avviso e 42 indica 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): string

mysqli_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:

FunzioneRestituisceNatura
mysqli_sqlstate()Una string a 5 caratteri come "42S02"Standard ANSI/ISO — portabile tra database
mysqli_errno()Un intero come 1146Specifico di MySQL — più granulare, ma non portabile
mysqli_error()Un messaggio leggibileIl 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 exist

Nota 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:

SQLSTATESignificato
00000Successo — nessun errore
23000Violazione di vincolo di integrità (es. chiave duplicata, errore di chiave esterna)
42000Errore di sintassi o violazione di regola di accesso
42S02Tabella o vista di base non trovata
42S22Colonna non trovata
HY000Errore generico (quando non si applica nessun codice specifico)
08S01Errore 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 blocco try/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 usa mysqli_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.

Esercizio

Pratica
Cosa restituisce la funzione mysqli_sqlstate() in PHP?
Cosa restituisce la funzione mysqli_sqlstate() in PHP?
Was this page helpful?