mysqli::multi_query boucle do...while infinie

Eléphant du PHP | 65 Messages

17 nov. 2016, 19:36

Bonsoir à tous,
J'aimerais comprendre pourquoi ce code produit une boucle infinie:

Code : Tout sélectionner

<?php $mysqli = new mysqli('localhost','user','pwd','test'); $query = "SELECT CURRENT_USER();"; $query.= "SELECT DATE_FORMAT(NOW(),'%d %m %Y');"; if($mysqli->multi_query($query)): do{ if($result = $mysqli->store_result()): while($row = $result->fetch_array()): printf('%s<br />',$row[0]); endwhile; $result->free(); endif; if($mysqli->more_results()): print '------------------<br />'; endif; }while(true === $mysqli->more_results()); endif; $mysqli->close();
Je n'arrive pas à comprendre :oops:

ynx
Mammouth du PHP | 586 Messages

18 nov. 2016, 10:14

Salut,

Il semble que tu dois appeler la fonction mysqli->next_result() pour préparer le prochain résultat de requête sans boucler sur le même résultat.
Le premier exemple de la doc de la fonction multi_query() montre la solution à ton problème en appelant la fonction mysqli->next_result() dans la condition de la boucle do while : http://php.net/manual/fr/mysqli.multi-q ... ample-1910

Bonne journée,

Eléphant du PHP | 65 Messages

18 nov. 2016, 10:55

@ynx
En fait c'est justement PHP qui m'a déclenché une erreur stricte à cause de l'exemple de la doc officielle - je suis sous PHP 7.0.8 - :

Strict standards: mysqli::next_result() [mysqli.next-result.html: There is no next result set. Please, call mysqli_more_results()/mysqli::more_results() to check whether to call this function/method in E:\users\...

Erreur tout à fait logique quand on y pense... On dirait que c'est un bug - je n'utilise pas le strict type -.

ynx
Mammouth du PHP | 586 Messages

18 nov. 2016, 11:58

Effectivement cette erreur semble connue et pas très récente (depuis PHP 5.3 apparemment), étonnant que la doc n'en parle quasiment pas (à part dans les commentaires) : http://php.net/manual/fr/mysqli.multi-query.php#100018

La correction proposée est d'appeler la fonction more_results() et next_result() dans le condition do while :
while ($mysqli->more_results() && $mysqli->next_result());

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

18 nov. 2016, 12:30

Bonjour,

Le problème est en fait le même que lorsque l'on utilise une variable sans en vérifier l'existence au préalable.
Le next_result permet de passer au resultset suivant. Sans lui, tu boucles toujours sur la même ligne de résultat.
Le more_results permet de vérifier s'il existe bien un resultset suivant sur lequel passer.

La solution de ynx est effectivement la meilleure et pour la doc officielle, je ne suis pas sur qu'ils utilisent le paramètre strict pour leurs exemples. Les commentaires apportent souvent des informations complémentaires indispensables :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...