multi_query
Découvrez la fonction mysqli_multi_query() en PHP pour exécuter plusieurs requêtes SQL en un seul appel, avec exemples et bonnes pratiques.
Dans cet article, nous allons nous concentrer sur la fonction mysqli_multi_query() en PHP, qui exécute une ou plusieurs instructions SQL en un seul appel. Nous aborderons sa syntaxe, ses paramètres et sa valeur de retour, présenterons un exemple exécutable et expliquerons comment lire plusieurs ensembles de résultats en toute sécurité.
Qu'est-ce que mysqli_multi_query() ?
mysqli_multi_query() est une fonction PHP intégrée qui envoie une ou plusieurs instructions SQL, séparées par des points-virgules, au serveur MySQL en un seul aller-retour. Elle fait partie de l'extension MySQLi, l'interface améliorée de PHP pour communiquer avec MySQL.
Elle est pratique lorsque vous avez un lot d'instructions à exécuter en une fois — par exemple, l'initialisation de plusieurs tables lors d'une configuration, ou l'exécution d'une procédure stockée qui retourne plusieurs ensembles de résultats. Étant donné que chaque instruction s'exécute toujours indépendamment sur le serveur, mysqli_multi_query() n'est pas un substitut à une transaction lorsque vous avez besoin d'un comportement tout-ou-rien (voir Quand ne pas l'utiliser).
Syntaxe
La fonction fonctionne à la fois en style procédural et orienté objet :
// Procedural style
mysqli_multi_query(mysqli $mysqli, string $query): bool
// Object-oriented style
$mysqli->multi_query(string $query): boolParamètres
| Paramètre | Description |
|---|---|
$mysqli | Une connexion valide retournée par mysqli_connect(). |
$query | Une chaîne d'une ou plusieurs instructions SQL séparées par un point-virgule (;). |
Valeur de retour
La fonction retourne false si la première instruction échoue, sinon true. Une valeur de retour true signifie seulement que la première requête a été acceptée — vous devez itérer sur les résultats pour détecter les erreurs dans les instructions suivantes.
Comment utiliser mysqli_multi_query()
Appelez la fonction sur une connexion MySQLi valide avec une chaîne d'instructions séparées par des points-virgules, puis parcourez les ensembles de résultats en boucle. Voici un exemple complet :
<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");
if (!$mysqli) {
die("Connection failed: " . mysqli_connect_error());
}
$query = "INSERT INTO table1 VALUES ('value1', 'value2', 'value3');";
$query .= "UPDATE table2 SET column1 = 'newvalue' WHERE id = 1;";
if (mysqli_multi_query($mysqli, $query)) {
do {
if ($result = mysqli_store_result($mysqli)) {
while ($row = mysqli_fetch_row($result)) {
print_r($row);
}
mysqli_free_result($result);
}
} while (mysqli_next_result($mysqli));
} else {
echo "Error: " . mysqli_error($mysqli);
}
mysqli_close($mysqli);
?>Voici ce que fait chaque partie :
mysqli_connect()ouvre une connexion à la base de données MySQL ; nous interrompons l'exécution immédiatement en cas d'échec.- Nous construisons une chaîne unique contenant deux instructions séparées par des points-virgules.
mysqli_multi_query()envoie les deux instructions au serveur en un seul appel.- La boucle
do...whilelit chaque ensemble de résultats à tour de rôle.mysqli_store_result()met en mémoire tampon le résultat actuel,mysqli_fetch_row()lit ses lignes, etmysqli_next_result()passe au suivant. mysqli_close()libère la connexion.
Gestion de plusieurs ensembles de résultats
C'est la partie que les développeurs se trompent le plus souvent. Après un mysqli_multi_query() réussi, vous devez consommer chaque ensemble de résultats — même les vides produits par INSERT ou UPDATE — avant de pouvoir exécuter une autre requête sur la même connexion. Ignorer cette étape déclenche une erreur "Commands out of sync".
Le schéma sécurisé est le suivant :
<?php
do {
// Buffer the current result set, if any.
if ($result = mysqli_store_result($mysqli)) {
while ($row = mysqli_fetch_row($result)) {
print_r($row);
}
mysqli_free_result($result);
}
// mysqli_more_results() avoids a spurious warning on the last loop.
} while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli));
?>mysqli_next_result() retourne false lorsqu'il n'y a plus de résultats, ce qui fait sortir de la boucle. Vérifier mysqli_more_results() en premier empêche l'émission d'un avertissement après la dernière instruction.
Quand ne pas l'utiliser
mysqli_multi_query() est puissant mais facile à mal utiliser :
- Ne transmettez jamais directement des données saisies par l'utilisateur dans la chaîne de requête. Concaténer des données non fiables ici est un vecteur classique d'injection SQL, et cette fonction ne peut pas utiliser de paramètres liés. Pour tout ce qui implique des données utilisateur, exécutez chaque instruction séparément avec des requêtes préparées — voir
mysqli_prepare(). - Elle n'est pas atomique. Si la deuxième instruction échoue, la première a déjà été validée. Lorsque plusieurs instructions doivent réussir ou échouer ensemble, encapsulez les requêtes dans une transaction avec
mysqli_begin_transaction(),mysqli_commit()etmysqli_rollback(). - Vérifiez toujours la valeur de retour et itérez les résultats pour détecter les erreurs dans les instructions après la première.
Conclusion
La fonction mysqli_multi_query() vous permet d'exécuter plusieurs instructions SQL en un seul appel, ce qui est pratique pour les opérations par lots. La clé pour l'utiliser correctement est de consommer chaque ensemble de résultats avec mysqli_next_result() afin d'éviter les erreurs "Commands out of sync", et de recourir aux requêtes préparées et aux transactions dès que des données utilisateur ou l'atomicité sont en jeu.