next_result
In questo articolo ci concentriamo sulla funzione mysqli_next_result() in PHP, usata per preparare il prossimo risultato di mysqli_multi_query().
Quando si inviano più istruzioni SQL a MySQL in un'unica chiamata con mysqli_multi_query(), il server restituisce i risultati un set alla volta. mysqli_next_result() è la funzione che consente di passare dal set di risultati corrente a quello successivo, in modo da poterli elaborare tutti in un ciclo. Questo articolo spiega cosa restituisce la funzione, i parametri che accetta, gli errori comuni e come usarla sia nello stile procedurale che orientato agli oggetti di MySQLi.
Cosa fa mysqli_next_result()
mysqli_next_result() prepara il set di risultati successivo da una precedente chiamata a mysqli_multi_query() e lo rende disponibile per le funzioni di recupero come mysqli_store_result() o mysqli_fetch_assoc(). Internamente, MySQL memorizza nel buffer tutti i set di risultati di una multi-query; questa funzione avanza il puntatore interno di uno step.
Importante: una singola chiamata a mysqli_next_result() avanza di un solo passo. Per elaborare ogni istruzione, si chiama la funzione all'interno di un ciclo finché non rimangono risultati.
Sintassi
// Procedural style
mysqli_next_result(mysqli $mysql): bool
// Object-oriented style
$mysqli->next_result(): boolParametri
$mysql(solo procedurale) — l'oggetto connessione restituito damysqli_connect(). Nello stile OOP è l'oggetto su cui si chiama il metodo.
Valore restituito
Restituisce un boolean:
true— il set di risultati successivo è stato preparato con successo (o non vi erano altri risultati e non si è verificato alcun errore).false— si è verificato un errore nell'istruzione successiva, oppure la query precedente non aveva risultati bufferizzati su cui avanzare.
Per distinguere "non ci sono altri risultati" da "l'istruzione successiva ha generato un errore", si usa insieme a mysqli_more_results(): se mysqli_more_results() è true ma mysqli_next_result() restituisce false, l'istruzione successiva ha generato un errore.
Come usare mysqli_next_result() (stile procedurale)
Eseguire il batch con mysqli_multi_query(), elaborare il primo set di risultati, quindi eseguire un ciclo finché ci sono altri risultati, avanzando con mysqli_next_result() ad ogni iterazione:
<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");
if (!$mysqli) {
die("Connection failed: " . mysqli_connect_error());
}
$query = "SELECT name FROM users LIMIT 1;";
$query .= "SELECT title FROM posts LIMIT 1;";
if (mysqli_multi_query($mysqli, $query)) {
do {
// mysqli_store_result() returns false for statements that
// produce no rows (INSERT, UPDATE, DELETE), so guard with if.
if ($result = mysqli_store_result($mysqli)) {
while ($row = mysqli_fetch_assoc($result)) {
print_r($row);
}
mysqli_free_result($result);
}
// Stop when there are no more results; otherwise advance.
} while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli));
} else {
echo "Multi-query failed: " . mysqli_error($mysqli);
}
mysqli_close($mysqli);
?>La condizione do...while è l'idea chiave: mysqli_more_results() verifica se esiste un altro set, e mysqli_next_result() avanza effettivamente ad esso. Poiché && esegue il cortocircuito, mysqli_next_result() viene chiamata solo quando esiste davvero un altro risultato, evitando così l'avviso che si otterrebbe chiamandola oltre l'ultimo set.
Stile orientato agli oggetti
La stessa logica con l'API OOP risulta leggermente più leggibile:
<?php
$mysqli = new mysqli("localhost", "username", "password", "database");
if ($mysqli->connect_errno) {
die("Connection failed: " . $mysqli->connect_error);
}
$sql = "SELECT name FROM users LIMIT 1;";
$sql .= "SELECT title FROM posts LIMIT 1;";
if ($mysqli->multi_query($sql)) {
do {
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$result->free();
}
} while ($mysqli->more_results() && $mysqli->next_result());
}
$mysqli->close();
?>Errori comuni
- Svuotare sempre la coda. Se si esegue un'altra query mentre i set di risultati di una precedente
mysqli_multi_query()sono ancora in sospeso, MySQLi lancia "Commands out of sync". Eseguire il ciclo conmysqli_next_result()finchémysqli_more_results()èfalseprima di emettere una nuova query. - Dimenticare
mysqli_store_result()per istruzioni non SELECT. Istruzioni comeINSERTnon producono alcun set di risultati, quindimysqli_store_result()restituiscefalse— questo è previsto, non un errore. La guardiaif ($result = ...)gestisce il caso. - La multi-query è un rischio di SQL injection. Passare a
mysqli_multi_query()solo SQL affidabile e controllato dal server. Non concatenare mai input utente in una stringa multi-istruzione; usare le prepared statement per i dati utente.
Conclusione
mysqli_next_result() è la funzione che consente di scorrere tutti i set di risultati restituiti da una singola chiamata a mysqli_multi_query(). Usata insieme a mysqli_more_results() all'interno di un ciclo do...while, permette di elaborare in modo sicuro l'output di ciascuna istruzione e mantiene la connessione sincronizzata. Per ulteriori informazioni sul flusso di lavoro correlato, vedere mysqli_multi_query() e mysqli_fetch_assoc().