Page 1 sur 1

Les boucles WHILE

Posté : 26 juil. 2007, 08:43
par toto5710
Bonjour,

Voilà j'ai un petit soucis avec une boucle WHILE :

Code : Tout sélectionner

$connection1 = mysql_connect($hote, $util ,$pass) or die ("pas de connexion"); $db1 = mysql_select_db($base, $connection1) or die ("acces à la base impossible"); $auj = date ("Y-m-j"); $rq1 = "SELECT * from agenda WHERE date >= '$auj' ORDER BY date LIMIT 5, 1"; $result1 = mysql_query($rq1) or die ("Execution impossible"); while ($ligne = mysql_fetch_array($result1)) { extract($ligne) ; echo "texte01"; }
Dans cette boucle, si ma requete aboutie à un resultat, on affiche "texte01", mais comment faire en sorte que si, la requete ne donne aucun resultat on affiche "texte02" par exemple.

Merci d'avance

Posté : 26 juil. 2007, 09:03
par d0m
Si tu parles d'aucun résultat dans le sens aucune ligne de la table ne correspond aux conditions du SELECT,
alors il suffit de mettre un compteur initialisé à 0 avant ton while et de l'incrémenter dans la boucle.
Ensuite après la boucle tu testes si le compteur est égal à 0, tu écris ton texte02

OU

utiliser la fonction mysql_num_rows() pour compter le nombre de lignes renvoiées par la requête. Si elle est égale à 0, tu écris texte02, sinon tu traites les résultats de la requête avec ta boucle while.

Posté : 26 juil. 2007, 09:18
par Genova
Généralement pour gérer ces cas de figure je fais :
$sql = 'SELECT ... bla bla';
$result = mysql_query($sql) OR die(mysql_error());
if ($row = mysql_fetch_assoc($result))
{
   do
   {

   }
   while ($row = mysql_fetch_assoc($result));
}
else
{
   // Aucun résultat trouvé !
}

Posté : 26 juil. 2007, 12:14
par Ryle
Peronnellement je trouve plus agréable l'utilisation d'un compteur ou de la fonction mysql_num_rows() suggéré par d0m ... et je suis particulièrement contre l'utilisation de la structure do/while lorsque l'on est pas certain que le code devra être exécuté au moins une fois
if (mysql_num_rows($result) == 0) { 
   // Aucun résultat trouvé ! 
}
else { // le else est facultatif, le while faisant le test des résultats également
  while ($row = mysql_fetch_assoc($result)) { // s'il y a des résultat et tant qu'il y en a
    ... 
  } 
}

Posté : 26 juil. 2007, 12:39
par Hubert Roksor
Je ne suis pas fan de mysql_num_rows() et je recommande vraiment la méthode proposée par Genova. L'utilisation de mysql_num_rows() présume que le résultat est systématiquement mis en tampon, ce qui empêche en théorie pas mal d'optimisations. Par exemple, mettre les résultats en tampon en tâche de fond, même si je doute qu'une bibliothèque MySQL propose ça à l'heure actuelle. Ça empêche également l'utilisation de mysql_unbuffered_query().

Tout ça pour dire que mysql_num_rows() en fait plus que nécessaire (compte le nombre de lignes alors que l'on veut seulement tester l'existence d'un résultat), et j'aurais tendance à aller à l'économie.
je suis particulièrement contre l'utilisation de la structure do/while lorsque l'on est pas certain que le code devra être exécuté au moins une fois
Ça j'ai pas compris, est-ce que tu as raté le premier if ? Pour éviter d'enterrer sa condition d'erreur trop profondément dans le script on peut procéder dans l'autre sens
if (!$row = mysql_fetch_assoc($result))
{
}
else
{
	do
	{
	}
	while ($row = mysql_fetch_assoc($result));
}

Posté : 27 juil. 2007, 09:47
par toto5710
Ok merci :lol: c'est parfait ca marche j'ai réussi

Posté : 27 juil. 2007, 12:07
par Ryle
je suis particulièrement contre l'utilisation de la structure do/while lorsque l'on est pas certain que le code devra être exécuté au moins une fois
Ça j'ai pas compris, est-ce que tu as raté le premier if ? Pour éviter d'enterrer sa condition d'erreur trop profondément dans le script on peut procéder dans l'autre sens
if (!$row = mysql_fetch_assoc($result))
{
}
else
{
	do
	{
	}
	while ($row = mysql_fetch_assoc($result));
}
Nonon, je n'ai pas loupé le if :)

La structure do/while (par rapport au while/do) sert a être sur que le code sera exécuté au moins une fois, il n'a aucun intérêt si l'on rajoute le même test autour pour que ce ne soit pas le cas. Il va du coup se comporter comme un while avec simplement du code en plus et une condition inutilement répétée (dans le if et dans le while) ...

Après ça reste que mon avis, mais je vois pas l'intérêt de "détourner" et bricoler des fonctions ou des structures, quand d'autres produisent déjà l'effet désiré :)

Posté : 27 juil. 2007, 14:27
par Hubert Roksor
Ben euh... oui, if + do c'est comme un while, mais qui possèderait un else. Pour moi ce n'est pas du détournement, la fonction de while est de répéter une boucle tant qu'une condition est vraie, en la vérifiant avant chaque itération. La fonction de do/while est de répéter une boucle tant qu'une condition est vraie, en la vérifiant après chaque itération. Pour moi il s'agit de la même structure, le mot-clé "do" est utilisé pour des raisons syntaxiques.

Si tu vois if + do comme un détournement, alors que dire de num_rows() ? Sur le principe c'est comparable à l'utilsation d'un SELECT COUNT(*) ou count($arr) pour vérifier si une table ou un tableau est vide... L'utilisation de num_rows() présume que le set de résultat est parfaitement connu (prefetched, c'est pour quoi ça ne fonctionne pas sur mysql_unbuffered_query()). Sur le principe, ça forcerait un driver qui implémente le résultat d'une requête SELECT sous la forme d'un curseur à faire plus de boulot pour voir jusqu'où les résultats courent. D'ailleurs, je crois me rappeler qu'à l'époque de la préhistoire (PHP4) il était délicat d'obtenir ce nombre à partir des autres SGBD sans pré-charger tous les résultats soi-même.

J'espère avoir clarifié ma position, et même si ça peut être perçu comme un détail je pense qu'on doit éviter le plus possible d'utiliser des informations précises ("combien de x dans le set ?") quand une information plus vague ("est-ce qu'il y a un x dans le set ?") est directement accessible et peut être utilisée à la place.
une condition inutilement répétée (dans le if et dans le while)
Juste pour vérifier, et pour m'assurer que ce passage n'est pas mal interprété (je me suis fait avoir à la première lecture), quand tu dis "condition inutilement répétée" tu parles bien de l'action de copier/coller le code, et non de son exécution ? Que ce soit if+do ou while, la condition est vérifiée i+1 fois, où i est le nombre d'itérations.

Posté : 27 juil. 2007, 15:36
par Sékiltoyai
Sinon, si on ne veut pas se faire chier (euh, s'importunner :) ) avec des débats inutiles, il y a aussi cela :
while( $row = mysql_fetch_array($result) )
{

}

if(mysql_num_rows($result)<=0)
{

}
Tout le monde est content : On a utilisé un mysql_num_rows(), mais pas mal, parce que si on a une unbuffered query, le mysql_num_rows() aura enregistré le nombre d'enregistrement retournés, et on a évité la répétition maladroite de mysql_fetch_*() avec une structure bancale du style if + do while.

Posté : 27 juil. 2007, 16:02
par Ryle
Bon bien sur c'est pinailler pour pas grand chose je le reconnais, mais j'apporterais juste une petite modification sur ta définition du do/while, et qui explique mon point de vue :
La fonction de do/while est d'exécuter une instruction et de la répéter en boucle tant qu'une condition est vraie, en la vérifiant après chaque itération.

L'instruction d'un do/while est exécutée de 1 à n fois, tandis que celle d'un while le sera de 0 à n fois. C'est cette notion d'exécution obligatoire que je trouve innaproprié si l'on doit en plus ajouter un test pour savoir s'il faut l'exécutée ou non :)

Pour le num_rows() je suis entièrement d'accord, j'ignorais ces détails de fonctionnement, et j'avoue que personnellement j'utilise soit un count(*) (pour savoir combien il y a de résultats au total) soit un bête compteur que j'incrémente (pour savoir combien j'en affiche) :)

Quant au code redondant, c'est effectivement l'écriture de celui-ci et pas son exécution. Par principe j'aime pas avoir le même code à deux endroits différents parce que je ne pense jamais qu'il me faut aller également modifier l'autre pour que cela fonctionne ;)

@Sékiltoyai : bah c'est pas forcément inutile comme débat, on ne cherche pas a savoir quelle est la meilleure solution (y en a générallement pas, c'est tellement souvent du cas par cas :)), mais ça permet de voir comment les autres travaillent et d'expliquer pourquoi. Et ça nous permet de trouver un bon compromis comme celui que tu proposes :)

Posté : 27 juil. 2007, 21:42
par Sékiltoyai
j'avoue que personnellement j'utilise soit un count(*) (pour savoir combien il y a de résultats au total) soit un bête compteur que j'incrémente (pour savoir combien j'en affiche) :)
Le problème du count(), c'est que bon, sur des requètes SQL...
Dans l'esprit, pour savoir si la boucle a été exécutée, il y a aussi le truc d'utiliser une variable initialisée à faux avant la requète, et mise à vraie dans la boucle while, de manière à vérifier que la requète a des résultats.
Quant au code redondant, c'est effectivement l'écriture de celui-ci et pas son exécution. Par principe j'aime pas avoir le même code à deux endroits différents parce que je ne pense jamais qu'il me faut aller également modifier l'autre pour que cela fonctionne ;)
Bah le problème est surtout que esthétiquement, c'est moche...
bah c'est pas forcément inutile comme débat, on ne cherche pas a savoir quelle est la meilleure solution (y en a générallement pas, c'est tellement souvent du cas par cas :)), mais ça permet de voir comment les autres travaillent et d'expliquer pourquoi. Et ça nous permet de trouver un bon compromis comme celui que tu proposes :)
C'était surtout pour la provoc que je disais cela, bien sur je pense aussi que c'est utile (enfin, pas trop inutile :P )