W3docs

PHP mysqli_use_result() — Ensembles de résultats non mis en mémoire tampon

Apprenez comment mysqli_use_result() initie un ensemble de résultats MySQL non bufférisé, ses différences avec mysqli_store_result() et quand l'utiliser.

Lorsque vous exécutez un SELECT en PHP avec l'extension mysqli, MySQL doit transmettre les lignes correspondantes à votre script. Il existe deux façons de les recevoir : bufférisée (copier l'intégralité du résultat dans la mémoire PHP d'un coup) et non bufférisée (laisser les lignes sur le serveur MySQL et les récupérer une par une). La fonction mysqli_use_result() initie le mode non bufférisé.

Ce guide explique ce que fait mysqli_use_result(), en quoi il diffère du mode bufférisé par défaut, les règles à respecter lors de son utilisation, et quand il vaut vraiment la peine d'y recourir.

Ce que fait mysqli_use_result()

mysqli_use_result() initie la récupération d'un ensemble de résultats produit par une requête, sans copier les lignes dans la mémoire PHP. Au lieu de télécharger toutes les lignes à l'avance, le serveur conserve les lignes et votre script les récupère une par une au fur et à mesure de la boucle.

Comparez cela avec le comportement par défaut. Lorsque vous appelez mysqli_query(), mysqli appelle mysqli_store_result() en interne — il tire l'intégralité de l'ensemble de résultats en mémoire cliente avant que votre code ne voie une seule ligne. Pour une requête retournant dix millions de lignes, cela peut représenter des centaines de mégaoctets de mémoire PHP. mysqli_use_result() évite ce coût : l'utilisation de la mémoire reste approximativement constante quel que soit le nombre de lignes retournées par la requête.

Syntaxe

mysqli_use_result(mysqli $mysql): mysqli_result|false

Elle prend l'objet de connexion (ou lien) retourné par mysqli_connect() et retourne un objet mysqli_result en cas de succès, ou false en cas d'échec. En style orienté objet, la méthode équivalente est $mysqli->use_result().

Bufférisé vs. non bufférisé : pourquoi la distinction est importante

Bufférisé (store_result)Non bufférisé (use_result)
Mémoire côté PHPContient l'ensemble du résultatEnviron une ligne à la fois
mysqli_num_rows()Disponible immédiatementSeulement après la récupération de toutes les lignes
mysqli_data_seek()Pris en chargeNon pris en charge
La connexion pendant la lectureLibre pour de nouvelles requêtesVerrouillée jusqu'à la fin
Idéal pourEnsembles de résultats petits/moyensTrès grands ensembles de résultats

Le principal compromis : le mode non bufférisé est léger en mémoire mais mobilise la connexion. Vous ne pouvez pas exécuter une autre requête sur la même connexion tant que vous n'avez pas récupéré toutes les lignes (ou libéré le résultat). Le mode bufférisé est l'inverse — plus gourmand en mémoire, mais la connexion est libre dès que la requête retourne.

Comment utiliser mysqli_use_result()

1. Se connecter au serveur MySQL

Ouvrez d'abord une connexion avec mysqli_connect() :

<?php

$host     = 'localhost';
$user     = 'username';
$password = 'password';
$database = 'mydatabase';

$connection = mysqli_connect($host, $user, $password, $database);

if (!$connection) {
    die('Connection failed: ' . mysqli_connect_error());
}

2. Exécuter la requête, puis démarrer la récupération non bufférisée

Pour le mode non bufférisé, vous devez exécuter la requête sans demander à mysqli de stocker le résultat. Utilisez le drapeau MYSQLI_USE_RESULT avec mysqli_query() (ou appelez mysqli_real_query()), puis appelez mysqli_use_result() :

$sql = "SELECT id, name FROM users";

// MYSQLI_USE_RESULT tells mysqli NOT to buffer the rows.
mysqli_real_query($connection, $sql);

$result = mysqli_use_result($connection);

if ($result) {
    while ($row = mysqli_fetch_assoc($result)) {
        // Process one row at a time — only this row lives in PHP memory.
        print_r($row);
    }
    mysqli_free_result($result);
}

Chaque appel à mysqli_fetch_assoc() tire la ligne suivante directement depuis le réseau. Vous pouvez également utiliser mysqli_fetch_row(), mysqli_fetch_array(), ou mysqli_fetch_all() de la même façon.

3. Toujours libérer le résultat

L'appel à mysqli_free_result() est plus important ici qu'en mode bufférisé : tant que le résultat n'est pas libéré (ou entièrement lu), la connexion reste verrouillée et inutilisable pour toute autre requête.

Règles et pièges

  • Lisez toutes les lignes avant la prochaine requête. Tant qu'un résultat non bufférisé est ouvert, la connexion est occupée. Tenter d'exécuter une autre requête avant d'avoir terminé la boucle provoque une erreur "Commands out of sync". Terminez la boucle ou appelez mysqli_free_result() d'abord.
  • Pas de comptage de lignes à l'avance. mysqli_num_rows() ne retourne le nombre correct qu'après avoir récupéré toutes les lignes, car le serveur n'a pas encore informé le client du nombre total.
  • Pas d'accès aléatoire. mysqli_data_seek() ne fonctionne pas sur les résultats non bufférisés — vous ne pouvez avancer que dans un seul sens.
  • Un seul résultat par connexion. Vous ne pouvez maintenir qu'un seul résultat non bufférisé ouvert sur une connexion à la fois.

Quand l'utiliser ?

Utilisez mysqli_use_result() lorsqu'une requête retourne beaucoup plus de données que vous ne souhaitez conserver en mémoire — exporter une grande table vers un CSV, diffuser un rapport, ou alimenter un long résultat ligne par ligne dans un autre processus. Dans ces cas, l'empreinte mémoire constante constitue un vrai avantage.

Pour les requêtes courantes qui retournent quelques lignes, voire quelques milliers, restez avec le mode bufférisé par défaut via mysqli_query(). La commodité de mysqli_num_rows(), la navigation aléatoire et une connexion libre l'emportent presque toujours sur l'économie de mémoire modeste.

Conclusion

mysqli_use_result() démarre un ensemble de résultats MySQL non bufférisé, récupérant les lignes une par une afin que l'utilisation de la mémoire reste faible même pour de très grands ensembles de résultats. Le coût est que la connexion est verrouillée jusqu'à la fin de la lecture, vous perdez mysqli_num_rows() et mysqli_data_seek(), et vous devez libérer le résultat rapidement. Utilisez-le pour de véritables ensembles de données volumineux ; préférez le mode bufférisé par défaut pour les requêtes ordinaires.

Pratique

Pratique
Quelles sont les façons d'utiliser un résultat de MySQL en PHP ?
Quelles sont les façons d'utiliser un résultat de MySQL en PHP ?
Was this page helpful?