insert_id
In questo articolo approfondiamo la funzione mysqli_insert_id() in PHP, usata per recuperare l'ID generato dalla precedente query INSERT.
Quando si inserisce una riga in una tabella che ha una chiave primaria AUTO_INCREMENT (o SERIAL), il database genera automaticamente il nuovo ID. La funzione mysqli_insert_id() consente di leggere quel valore generato direttamente in PHP subito dopo l'inserimento, in modo da poterlo usare come chiave esterna, restituirlo in una risposta API o reindirizzare l'utente al nuovo record.
Questo articolo spiega cosa restituisce mysqli_insert_id(), sia la sintassi procedurale che quella orientata agli oggetti, e le insidie più comuni che portano a ricevere un valore errato (o 0).
Cosa restituisce mysqli_insert_id()
mysqli_insert_id() restituisce l'ID generato dall'ultima query che ha inserito dati in una colonna AUTO_INCREMENT, per la connessione specificata.
- Se la query precedente ha memorizzato un valore in una colonna
AUTO_INCREMENT, restituisce quel valore. - Se la query precedente non era un
INSERT/UPDATEche ha interessato una colonnaAUTO_INCREMENT, restituisce0. - Il valore è limitato alla connessione corrente, quindi gli inserimenti concorrenti di altri client non influenzano mai il risultato. Questo la rende sicura anche su un server molto occupato.
Nota: il valore riflette il primo ID generato automaticamente dall'istruzione. Per un inserimento a riga singola si tratta dell'ID della riga; per un inserimento a più righe è l'ID della prima riga.
Sintassi
mysqli_insert_id() accetta la connessione MySQLi come unico argomento:
int|string mysqli_insert_id(mysqli $mysql)In PHP moderno (8.1+), se una query fallisce MySQLi lancia un'eccezione mysqli_sql_exception anziché restituire false, quindi gli esempi seguenti presuppongono che gli errori vengano gestiti come eccezioni.
Esempio procedurale
Questo è lo stile più comune che si trova nei tutorial e nelle basi di codice più datate:
<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");
mysqli_query(
$mysqli,
"INSERT INTO users (name, email) VALUES ('Ada', '[email protected]')"
);
$id = mysqli_insert_id($mysqli);
echo "Last inserted ID is: " . $id;
mysqli_close($mysqli);
?>Qui apriamo una connessione con mysqli_connect(), eseguiamo un INSERT con mysqli_query(), poi leggiamo l'ID generato con mysqli_insert_id() prima di chiudere la connessione.
Esempio orientato agli oggetti
La stessa logica con l'interfaccia OOP, che la maggior parte del codice moderno utilizza. L'ID generato è esposto tramite la proprietà insert_id:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
$mysqli->query(
"INSERT INTO users (name, email) VALUES ('Ada', '[email protected]')"
);
echo "Last inserted ID is: " . $mysqli->insert_id;
$mysqli->close();
?>Utilizzo con le prepared statement
Nelle applicazioni reali è consigliabile inserire i dati dell'utente tramite una prepared statement per evitare SQL injection. L'ID dell'inserimento è comunque disponibile in seguito, sia dall'oggetto connessione che dall'oggetto statement:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);
$name = "Grace";
$email = "[email protected]";
$stmt->execute();
echo "New user id: " . $stmt->insert_id; // same as $mysqli->insert_id here
$stmt->close();
$mysqli->close();
?>Insidie comuni
- Leggilo immediatamente. Il valore riflette solo l'ultimo inserimento sulla connessione. Se esegui un altro
INSERT(anche in una tabella non correlata) prima di leggere il valore, otterrai l'ID di quell'inserimento. Salvalo in una variabile subito dopo l'inserimento. - Nessuna colonna
AUTO_INCREMENTsignifica0. Se la chiave primaria della tabella viene impostata manualmente, non viene generato nulla e la funzione restituisce0. UPDATEeSELECTazzerano le aspettative. UnUPDATEriuscito che non tocca una colonna auto-increment, o qualsiasiSELECT, non lascia alcun nuovo ID generato e la funzione restituisce0.- Gli inserimenti a più righe restituiscono il primo ID. Dopo
INSERT INTO t VALUES (...),(...),(...), si ottiene l'ID della prima riga inserita; le successive seguono in modo sequenziale.
Funzioni correlate
mysqli_affected_rows()— quante righe ha modificato l'ultima query.mysqli_query()— esegue l'INSERTdi cui si legge l'ID.- PHP MySQLi overview — l'estensione MySQLi completa.
- Insert data into MySQL — una guida completa sull'inserimento dati.
Conclusione
mysqli_insert_id() è il metodo standard per recuperare la chiave primaria auto-generata subito dopo un inserimento. Leggila immediatamente dopo l'INSERT, ricorda che è legata alla connessione (quindi è sicura nella concorrenza) e aspettati 0 ogni volta che l'ultima istruzione non ha generato un valore auto-increment.