Réexécution de la requête nécessaire ?

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

03 janv. 2007, 20:21

Salut et fraternité !

J'ai besoin d'utiliser deux fois le résultat d'une même requête.
Suis-je contraint et forcé de relancer l'exécution de celle-ci ?

Ceci fonctionne :
$req = "SELECT champs FROM table";
$res = mysql_query($req) or die ("Select planté");
while ($ligne1 = mysql_fetch_assoc($res))
      { // ...
      }
$res = mysql_query($req) or die ("Select planté"); // réexécution de la requête
while ($ligne2 = mysql_fetch_assoc($res))
      { // ...
      }
mais ceci ne fonctionne pas :
$req = "SELECT champs FROM table";
$res = mysql_query($req) or die ("Select planté");
while ($ligne1 = mysql_fetch_assoc($res))
      { // ...
      }
while ($ligne2 = mysql_fetch_assoc($res))
      { // ...
      }
Modifié en dernier par albat le 03 janv. 2007, 20:42, modifié 1 fois.

Eléphant du PHP | 217 Messages

03 janv. 2007, 20:33

Salut,
oui tu es obligé de la réexécuter.
Si tu n'as pas enormément de données à traiter tu peux stocker les lignes de résultats dans un tableau pour les réafficher plus tard.
A voir si tu gagnes en rapidité d'exécution entre cette méthode et le traitement simultané de deux requêtes.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

03 janv. 2007, 21:33

que nenni ... ;)

La fonction php mysql_data_seek() permet de déplacer le pointeur interne d'une ressource MySQL

Donc
$req = "SELECT champs FROM table";
$res = mysql_query($req) or die ("Select planté");
while ($ligne1 = mysql_fetch_assoc($res))
      { // ...
      }

//remise au départ du pointeur de parcours
mysql_data_seek($res, 0);

while ($ligne2 = mysql_fetch_assoc($res))
      { // ...
      }
Te permettra de parcourir 2 fois le même résultat sans réexécuter la requete.
J'aurais envi de te dire, mon cher Albat, que php.net est ton ami, surtout cette page qui contient toutes les fonction mysql : http://fr2.php.net/manual/fr/ref.mysql.php ;)

Mais permet moi de te demander pourquoi tu ne peux mutualiser les parcours et faire tous les traitements en 1 seule passe :-k
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

03 janv. 2007, 21:34

À priori non, à moins que tu aies désactivé le "buffering". Regardez du côté de mysql_data_seek().

Edit: grillé par zeus à 5s près :( bouh

Mammouth du PHP | 1885 Messages

04 janv. 2007, 08:58

Voilà. Ou alors tu récupères toutes les données dans un array() et t'espère ne pas en avoir trop pour pas faire sauter la mémoire.
La programmation est l'expression de la poésie d'un programmeur
Génération PHP

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

04 janv. 2007, 10:02

Pour ce qui est de la place mémoire, je n'ai pas spécialement de crainte.
La table contient une dizaine de champs, tous numériques (entiers, même !)
et ne devrait pas dépasser une centaine d'enregistrements.

ViPHP
AB
ViPHP | 5818 Messages

04 janv. 2007, 13:29

Albat
T'as pas oublié de mettre résolu?

Voilà. Ou alors tu récupères toutes les données dans un array() et t'espère ne pas en avoir trop pour pas faire sauter la mémoire.
...et cette méthode serait plus rapide ou plus simple ou moins gourmande en ressources que celle indiquée par Zeus ou par Hubert Roksor?
Comme je suis pas expert, si tu pouvais m'expliquer en deux mots...

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

04 janv. 2007, 13:30

Albat
T'as pas oublié de mettre résolu?
Non, non ! :lol:
Je suis en train de tester différentes solutions et je n'oublierai pas de revenir clore ce sujet. ;)

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

04 janv. 2007, 15:58

J'avais tenté, en bricolant un brin, de dupliquer le tableau de résultats comme le suggère Xenon_54,
mais j'ai finalement opté pour le mysql_data_seek() proposé par zeus et Hubert.

Et vous savez quoi ? Ça marche !!! :merci:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

05 janv. 2007, 01:55

cette méthode serait plus rapide ou plus simple ou moins gourmande en ressources que celle indiquée par Zeus ou par Hubert Roksor?
Il faut savoir que quand on exécute mysql_query(), PHP récupère immédiatement tous les enregistrements et les garde dans un coin de sa mémoire. (méthode appelée "buffering" ou "mise en mémoire tampon" par les vieux ou "en antémémoire" par les moins vieux)) Ensuite, chaque appel à mysql_fetch_assoc() prend le résultat dans la mémoire au lieu de faire appel à chaque fois à la base de données.

Tout ça pour dire que quand on exécute mysql_query() on a déjà tous les enregistrements en mémoire, et les mettre dans un tableau PHP revient à dupliquer ces données et donc utiliser plus de mémoire que nécessaire. (le double en gros) D'un point de vue des performances, je n'ai pas testé mais je pense qu'elles sont grossièrement équivalentes. D'un point de vue technique, l'accès à un tableau PHP est probablement plus rapide qu'appeler une fonction (mysql_fetch_assoc()) mais il faudrait prendre en compte le temps passé à créer ce tableau, etc... en gros ça n'en vaut pas la peine.

Pour info, si vous n'avez pas envie que mysql_query() charge directement tous les résultats, si vous récupérez par exemple l'intégralité d'une table, utilisez mysql_unbuffered_query() à la place. Attention, cette dernière peut être plus lente, à n'utiliser que si vous en avez besoin.

Mammouth du PHP | 1885 Messages

05 janv. 2007, 07:59

Une fois les données récupérées, tu peux fermer la connexion MySLQ plus rapidement et effectuer le traitement immédiatement après.

Ta connexion ne sera donc pas en suspendu durant le traitement. (parfois long)

De plus, l'utilisation d'un array s'appliquement seulement si tu ne peux activer la bufferisation.

Désactiver la bufferisation peut être utile si tu veux commencer le traitement avant la fin de la requête.
La programmation est l'expression de la poésie d'un programmeur
Génération PHP

ViPHP
AB
ViPHP | 5818 Messages

05 janv. 2007, 14:22

Hubert,
C'est bien parce que j'avais compris (dans les grandes lignes) ce que tu as expliqué, que je demandais à Xénon_54 pourquoi faire autrement.

Xénon_54,
Si j'ai bien compris :
Comme on peut utiliser un mysql_close() à la fin d'une requête sans perdre le résultat de la ressource qui est bufférisée, j'en conclu que l'intérêt de faire un tableau, c'est de pouvoir mémoriser le résultat de mysql_unbuffered_query() qu'on utilise (entre autre) pour pouvoir accéder à une partie de la ressource avant la fin de la requête.

Merci à tous les deux :lol: maintenant c'est plus clair.