next_result
Dieser Artikel erklärt die PHP-Funktion mysqli_next_result(), die das nächste Abfrageergebnis für mysqli_multi_query() vorbereitet.
Wenn Sie mit mysqli_multi_query() mehrere SQL-Anweisungen in einem Aufruf an MySQL senden, gibt der Server die Ergebnisse einen Ergebnissatz nach dem anderen zurück. mysqli_next_result() ist die Funktion, die Sie vom aktuellen Ergebnissatz zum nächsten wechseln lässt, sodass Sie alle durchlaufen können. Dieser Artikel erklärt, was die Funktion zurückgibt, welche Parameter sie entgegennimmt, häufige Fallstricke und wie sie sowohl im prozeduralen als auch im objektorientierten MySQLi-Stil verwendet wird.
Was mysqli_next_result() macht
mysqli_next_result() bereitet den nächsten Ergebnissatz aus einem vorherigen Aufruf von mysqli_multi_query() vor und macht ihn für Abruffunktionen wie mysqli_store_result() oder mysqli_fetch_assoc() verfügbar. Intern puffert MySQL alle Ergebnissätze einer Multi-Query; diese Funktion verschiebt den internen Zeiger um eine Position vorwärts.
Wichtig: Ein einzelner Aufruf von mysqli_next_result() bewegt Sie nur einen Schritt vorwärts. Um jede Anweisung zu verarbeiten, rufen Sie sie innerhalb einer Schleife auf, bis keine Ergebnisse mehr übrig sind.
Syntax
// Procedural style
mysqli_next_result(mysqli $mysql): bool
// Object-oriented style
$mysqli->next_result(): boolParameter
$mysql(nur prozedural) — das Verbindungsobjekt, das vonmysqli_connect()zurückgegeben wird. Im OOP-Stil ist dies das Objekt, auf dem Sie die Methode aufrufen.
Rückgabewert
Es wird ein boolean zurückgegeben:
true— der nächste Ergebnissatz wurde erfolgreich vorbereitet (oder es gab keine weiteren Ergebnisse und keinen Fehler).false— es gab einen Fehler in der nächsten Anweisung, oder die vorherige Abfrage hatte keine gepufferten Ergebnisse, zu denen weitergegangen werden könnte.
Um „keine weiteren Ergebnisse" von „die nächste Anweisung ist fehlgeschlagen" zu unterscheiden, kombinieren Sie es mit mysqli_more_results(): Wenn mysqli_more_results() true zurückgibt, aber mysqli_next_result() false zurückgibt, hat die nächste Anweisung einen Fehler ausgelöst.
Verwendung von mysqli_next_result() (prozeduraler Stil)
Führen Sie den Batch mit mysqli_multi_query() aus, verarbeiten Sie den ersten Ergebnissatz und durchlaufen Sie dann die Schleife, solange weitere Ergebnisse vorhanden sind, und rücken Sie mit mysqli_next_result() bei jedem Durchlauf vor:
<?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);
?>Die do...while-Bedingung ist der Kerngedanke: mysqli_more_results() prüft, ob ein weiterer Satz vorhanden ist, und mysqli_next_result() rückt tatsächlich zu diesem vor. Da && kurzschlussartig ausgewertet wird, wird mysqli_next_result() nur aufgerufen, wenn tatsächlich ein weiteres Ergebnis vorhanden ist, was die Warnung vermeidet, die Sie sonst erhalten würden, wenn Sie es nach dem letzten Satz aufrufen.
Objektorientierter Stil
Dieselbe Logik mit der OOP-API liest sich etwas übersichtlicher:
<?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();
?>Häufige Fallstricke
- Immer die Warteschlange leeren. Wenn Sie eine weitere Abfrage ausführen, während noch Ergebnissätze aus einem vorherigen
mysqli_multi_query()ausstehen, wirft MySQLi „Commands out of sync". Durchlaufen Sie die Schleife mitmysqli_next_result(), bismysqli_more_results()falsezurückgibt, bevor Sie eine neue Abfrage absetzen. mysqli_store_result()für Nicht-SELECT-Anweisungen vergessen. Anweisungen wieINSERTerzeugen keinen Ergebnissatz, daher gibtmysqli_store_result()falsezurück — das ist erwartet, kein Fehler. Derif ($result = ...)-Guard behandelt dies.- Multi-Query ist ein SQL-Injection-Risiko. Übergeben Sie an
mysqli_multi_query()niemals etwas anderes als vertrauenswürdiges, serverseitig kontrolliertes SQL. Verketten Sie niemals Benutzereingaben in einen Multi-Statement-String; verwenden Sie stattdessen Prepared Statements für Benutzerdaten.
Fazit
mysqli_next_result() ist die Funktion, mit der Sie alle Ergebnissätze durchlaufen können, die von einem einzelnen mysqli_multi_query()-Aufruf zurückgegeben werden. Zusammen mit mysqli_more_results() innerhalb einer do...while-Schleife verwendet, ermöglicht sie die sichere Verarbeitung der Ausgabe jeder Anweisung und verhindert, dass die Verbindung aus dem Sync gerät. Für mehr Informationen zum umgebenden Arbeitsablauf siehe mysqli_multi_query() und mysqli_fetch_assoc().