W3docs

next_result

Découvrez la fonction mysqli_next_result() en PHP, utilisée pour préparer le prochain résultat de mysqli_multi_query().

Lorsque vous envoyez plusieurs instructions SQL à MySQL en un seul appel avec mysqli_multi_query(), le serveur vous les renvoie un ensemble de résultats à la fois. mysqli_next_result() est la fonction qui vous fait passer de l'ensemble de résultats courant au suivant, afin que vous puissiez les parcourir tous. Cet article explique ce que la fonction retourne, les paramètres qu'elle accepte, les pièges courants et comment l'utiliser dans les styles procédural et orienté objet de MySQLi.

Ce que fait mysqli_next_result()

mysqli_next_result() prépare le prochain ensemble de résultats issu d'un appel précédent à mysqli_multi_query() et le rend disponible pour les fonctions de récupération telles que mysqli_store_result() ou mysqli_fetch_assoc(). En interne, MySQL met en mémoire tampon tous les ensembles de résultats d'une multi-requête ; cette fonction avance le pointeur interne d'un cran.

Important : un seul appel à mysqli_next_result() ne vous fait avancer que d'un pas. Pour traiter chaque instruction, vous l'appelez dans une boucle jusqu'à ce qu'il n'y ait plus de résultats.

Syntaxe

// Procedural style
mysqli_next_result(mysqli $mysql): bool

// Object-oriented style
$mysqli->next_result(): bool

Paramètres

  • $mysql (procédural uniquement) — l'objet de connexion retourné par mysqli_connect(). En style OOP, c'est l'objet sur lequel vous appelez la méthode.

Valeur de retour

Elle retourne un boolean :

  • true — le prochain ensemble de résultats a été préparé avec succès (ou il n'y avait plus de résultats et aucune erreur).
  • false — il y a eu une erreur dans la prochaine instruction, ou la requête précédente n'avait pas de résultats en mémoire tampon pour avancer.

Pour distinguer « il n'y a plus de résultats » de « la prochaine instruction a échoué », associez-la à mysqli_more_results() : si mysqli_more_results() retourne true mais que mysqli_next_result() retourne false, c'est que la prochaine instruction a déclenché une erreur.

Comment utiliser mysqli_next_result() (style procédural)

Exécutez le lot avec mysqli_multi_query(), traitez le premier ensemble de résultats, puis bouclez tant qu'il y a des résultats, en avançant avec mysqli_next_result() à chaque passage :

<?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 condition do...while est l'idée clé : mysqli_more_results() vérifie si un autre ensemble existe, et mysqli_next_result() avance effectivement vers celui-ci. Puisque && est court-circuité, mysqli_next_result() n'est appelé que lorsqu'un autre résultat existe réellement, ce qui évite l'avertissement que vous obtiendriez autrement en l'appelant après le dernier ensemble.

Style orienté objet

La même logique avec l'API OOP se lit un peu plus clairement :

<?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();
?>

Pièges courants

  • Toujours vider la file d'attente. Si vous exécutez une autre requête alors que des ensembles de résultats d'un mysqli_multi_query() précédent sont encore en attente, MySQLi lève "Commands out of sync". Bouclez avec mysqli_next_result() jusqu'à ce que mysqli_more_results() retourne false avant d'émettre une nouvelle requête.
  • Oublier mysqli_store_result() pour les instructions non-SELECT. Les instructions comme INSERT ne produisent aucun ensemble de résultats, donc mysqli_store_result() retourne false — c'est attendu, pas une erreur. Le garde if ($result = ...) le gère.
  • Les multi-requêtes sont un risque d'injection SQL. Ne transmettez que du SQL de confiance, contrôlé côté serveur, à mysqli_multi_query(). Ne concaténez jamais des données utilisateur dans une chaîne multi-instructions ; utilisez des instructions préparées pour les données utilisateur.

Conclusion

mysqli_next_result() est la fonction qui vous permet de parcourir chaque ensemble de résultats retourné par un seul appel à mysqli_multi_query(). Utilisée conjointement avec mysqli_more_results() dans une boucle do...while, elle vous permet de traiter la sortie de chaque instruction en toute sécurité et d'éviter que la connexion ne se désynchronise. Pour en savoir plus sur le flux de travail environnant, consultez mysqli_multi_query() et mysqli_fetch_assoc().

Pratique

Pratique
Que fait la fonction PHP mysqli::next_result ?
Que fait la fonction PHP mysqli::next_result ?
Was this page helpful?