Je me rends compte que cela fait un moment qu'il n'y a pas eu de nouvelle activité sur cette question. Mais, comme d'autres auteurs l'ont commenté - get_result()
n'est désormais disponible en PHP qu'en installant le pilote natif MySQL (mysqlnd), et dans certains cas, il peut ne pas être possible ou souhaitable d'installer mysqlnd. Donc, j'ai pensé qu'il serait utile de publier cette réponse avec des informations sur la façon d'obtenir la fonctionnalité get_result()
offerte - sans utiliser get_result()
.
get_result()
est / était souvent combiné avec fetch_array()
pour parcourir un jeu de résultats et stocker les valeurs de chaque ligne du jeu de résultats dans un tableau indexé numériquement ou associatif. Par exemple, le code ci-dessous utilise get_result () avec fetch_array () pour parcourir un jeu de résultats, en stockant les valeurs de chaque ligne dans le tableau $ data [] à indexation numérique:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Cependant, si get_result()
n'est pas disponible (car mysqlnd n'est pas installé), cela conduit au problème de savoir comment stocker les valeurs de chaque ligne d'un jeu de résultats dans un tableau, sans utiliser get_result()
. Ou comment migrer le code hérité qui get_result()
fonctionne sans lui (par exemple en utilisant à la bind_result()
place) - tout en impactant le moins possible le reste du code.
Il s'avère que stocker les valeurs de chaque ligne dans un tableau à indexation numérique n'est pas si simple à utiliser bind_result()
. bind_result()
attend une liste de variables scalaires (pas un tableau). Il faut donc du temps pour stocker les valeurs de chaque ligne du jeu de résultats dans un tableau.
Bien sûr, le code pourrait facilement être modifié comme suit:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Mais cela nous oblige à lister explicitement $ data [0], $ data [1], etc. individuellement dans l'appel à bind_result()
, ce qui n'est pas idéal. Nous voulons une solution qui ne nous oblige pas à lister explicitement $ data [0], $ data [1], ... $ data [N-1] (où N est le nombre de champs dans l'instruction select) dans l'appel à bind_results()
. Si nous migrons une application héritée qui a un grand nombre de requêtes, et que chaque requête peut contenir un nombre différent de champs dans la select
clause, la migration sera très laborieuse et sujette à des erreurs si nous utilisons une solution comme celle ci-dessus .
Idéalement, nous voulons un extrait de code de «remplacement» - pour remplacer uniquement la ligne contenant la get_result()
fonction et la boucle while () sur la ligne suivante. Le code de remplacement doit avoir la même fonction que le code qu'il remplace, sans affecter aucune des lignes avant, ni aucune des lignes après - y compris les lignes à l'intérieur de la boucle while (). Idéalement, nous voulons que le code de remplacement soit aussi compact que possible, et nous ne voulons pas avoir à adapter le code de remplacement en fonction du nombre de champs dans la select
clause de la requête.
En recherchant sur Internet, j'ai trouvé un certain nombre de solutions qui utilisent bind_param()
avec call_user_func_array()
(par exemple, lier dynamiquement les paramètres mysqli_stmt puis lier le résultat (PHP) ), mais la plupart des solutions que j'ai trouvées mènent finalement au stockage des résultats dans un tableau associatif, pas un tableau indexé numériquement, et beaucoup de ces solutions n'étaient pas aussi compactes que je le souhaiterais et / ou n'étaient pas adaptées en tant que «remplacements instantanés». Cependant, à partir des exemples que j'ai trouvés, j'ai pu bricoler cette solution, qui correspond à la facture:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Bien sûr, la boucle for () peut être réduite en une seule ligne pour la rendre plus compacte.
J'espère que cela aidera tous ceux qui recherchent une solution en utilisant bind_result()
pour stocker les valeurs de chaque ligne dans un tableau indexé numériquement et / ou qui recherchent un moyen de migrer le code hérité en utilisant get_result()
. Commentaires bienvenus.
$stmt = $conn->mysqli->stmt_init();
?