Problème d'affichage de résultats dans recherche par 4 listes déroulantes

Eléphanteau du PHP | 18 Messages

20 mars 2008, 11:09

Bonjour à tous,

Après de multiples recherches sur google et X forums je n'arrive pas à trouver la solution à mon problème.

J'ai crée un menu dans lequel on peut faire une recherche par 4 listes déroulantes. Chacune contient des informations sur une bdd MySql.
Mon formulaire marche parfaitement quand on sélectionne le contenu exacte des 4 listes.
Moi j'aimerai que quand l'on fait une recherche que sur une liste cela n'affiche que le résultat de cette liste et ignore les 3 autres.

Je cherche depuis 1 semaine mais je n'arrive pas à trouver mon problème, je ne maîtrise pas encore très bien le PHP.
Je pense que mon problème vient de mon code de recherche dans la table, au niveau du WHERE ...

Voici mes codes :

Le php de mes listes déroulantes (remplies par une table)
mysql_select_db($database_bdd, $bdd);
$query_rsetat = "SELECT * FROM etat";
$rsetat = mysql_query($query_rsetat, $bdd) or die(mysql_error());
$row_rsetat = mysql_fetch_assoc($rsetat);
$totalRows_rsetat = mysql_num_rows($rsetat);

mysql_select_db($database_bdd, $bdd);
$query_rstype = "SELECT * FROM type";
$rstype = mysql_query($query_rstype, $bdd) or die(mysql_error());
$row_rstype = mysql_fetch_assoc($rstype);
$totalRows_rstype = mysql_num_rows($rstype);

mysql_select_db($database_bdd, $bdd);
$query_rsbudget = "SELECT * FROM budget";
$rsbudget = mysql_query($query_rsbudget, $bdd) or die(mysql_error());
$row_rsbudget = mysql_fetch_assoc($rsbudget);
$totalRows_rsbudget = mysql_num_rows($rsbudget);

mysql_select_db($database_bdd, $bdd);
$query_rssecteur = "SELECT * FROM secteur";
$rssecteur = mysql_query($query_rssecteur, $bdd) or die(mysql_error());
$row_rssecteur = mysql_fetch_assoc($rssecteur);
$totalRows_rssecteur = mysql_num_rows($rssecteur);

$coletat_rsmulhouse = "0";
if (isset($_GET['etat'])) {
  $coletat_rsmulhouse = $_GET['etat'];
}
$colbudget_rsmulhouse = "0";
if (isset($_GET['budget'])) {
  $colbudget_rsmulhouse = $_GET['budget'];
}
$colsecteur_rsmulhouse = "0";
if (isset($_GET['secteur'])) {
  $colsecteur_rsmulhouse = $_GET['secteur'];
}
$coltype_rsmulhouse = "0";
if (isset($_GET['type'])) {
  $coltype_rsmulhouse = $_GET['type'];
}
Le code de ma recherche
mysql_select_db($database_bdd, $bdd);
$query_rsmulhouse = sprintf("SELECT * FROM mulhouse WHERE type_id_type = %s AND secteur_id_secteur = %s AND budget_id_budget =  %s AND etat_id_etat = %s  ", GetSQLValueString($coltype_rsmulhouse, "text"),GetSQLValueString($colsecteur_rsmulhouse, "text"),GetSQLValueString($colbudget_rsmulhouse, "text"),GetSQLValueString($coletat_rsmulhouse, "text"));
$rsmulhouse = mysql_query($query_rsmulhouse, $bdd) or die(mysql_error());
$row_rsmulhouse = mysql_fetch_assoc($rsmulhouse);
$totalRows_rsmulhouse = mysql_num_rows($rsmulhouse);
Une liste déroulante :

Code : Tout sélectionner

</select> <label for="secteur"></label> <select name="secteur" style="width:90%" id="secteur"> <?php do { ?> <option value="<?php echo $row_rssecteur['id_secteur']?>"><?php echo $row_rssecteur['secteur']?></option> <?php } while ($row_rssecteur = mysql_fetch_assoc($rssecteur)); $rows = mysql_num_rows($rssecteur); if($rows > 0) { mysql_data_seek($rssecteur, 0); $row_rssecteur = mysql_fetch_assoc($rssecteur); } ?> </select>

La table secteur :

0 Zone géographique ...
1 Quartier du Zoo
2 Centre ville
3 Quartier Europe
4 Porte jeune
5 Alentours


Merci d'avance à vous tous qui prendrez du temps pour m'aider :)

Charles

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

20 mars 2008, 13:07

Personnellement, j'ai jamais aimé l'utilisation de sprintf pour construire une requête SQL... c'est illisible, on ne sait pas à quel endroit vont les valeurs ni si leur nombre est cohérent etc.

A ta place, je construirais la chaine de ta requête SQL comme n'importe quelle chaine de caractères. Cela te permet notamment de concatener plusieurs éléments, et ainsi d'ajouter des tests si certains d'entre eux doivent être omis :)
$sql = "SELECT .... FROM mulhouse WHERE ... ";
if (....)
  $sql.= " AND type_id_type = ".GetSQLValueString($coltype_rsmulhouse, "text");
if (....)
  $sql.= " AND secteur_id_secteur = ". GetSQLValueString($colsecteur_rsmulhouse, "text")
...
Bon c'est a travailler un peu pour savoir quand mettre le WHERE ou les AND, mais voilà l'idée :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 18 Messages

20 mars 2008, 19:22

Merci Ryle pour ta réponse très rapide :D

C'est effectivement dans ce sens que je voulais partir, mais j'avais du mal a trouver la structure .
Je m'y attaque dès ce soir, et vous tiens au courant :)

Merci encore

Eléphanteau du PHP | 18 Messages

27 mars 2008, 15:32

Bonjour à tous,

Alors Ryle j'ai essayé de suivre ton conseil, qui je le pense est le bon, mais j'ai essayé, et essayé, et je ne suis arrivé à rien, je me suis emmêlé les pinceaux (les touches plutôt ;) )

Je n'aime pas trop demander ça, mais Ryle, pourrais tu juste me dire dans la première ligne ce que je dois insérer après where, et if, pour que je m'en sorte? ...
Mon but n'est pas de l'avoir tout fait, mais juste le début pour que de moi même j'apprenne.

Normalement un ami codeur devait m'aider dans les codes plus poussés, comme je ne touche à PHP que depuis 1 mois, mais il m'a fait faux bond ... :(

Merci d'avance à tous ceux qui voudront bien m'apporter leur aide

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

27 mars 2008, 15:52

En fait le if() te permet de tester si une valeur a été spécifiée pour une liste donnée. Si c'est le cas, alors tu vas ajouter la portion de code SQL correspondant :

Code : Tout sélectionner

SI un secteur a été spécifié ALORS complete la requête en ajoutant un filtre sur le secteur SI un budget a été spécifié ALORS complete la requête en ajoutant un filtre sur le budget ...
Pour savoir si une valeur a été spécifiée, il te suffit d'utiliser isSet() ou, puisque tu donnes par défaut la valeur 0 à chacune de tes variables, de tester si la valeur est différentes de 0
if (isset($_GET['secteur'])) // test si la valeur secteur a été passée en get
  $sql.= " ... ";

// ou bien 
if ($colsecteur_rsmulhouse != 0) // test si la valeur par défaut a été modifiée
  $sql.= " ... ";
Il y a toutefois un petit détail auquel il faut faire attention, c'est que la première condition (donc le premier if() qui sera vrai) devra débuter par un WHERE tandis que les suivantes devront commencer par un AND.

Il y a plusieurs façons de faire cela, je te laisse chercher un peu et nous montrer le code que tu auras obtenu. Et si tu ne vois pas bien comment faire on en reparle :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 18 Messages

27 mars 2008, 16:04

Merci beaucoup Ryle pour cette explication très claire :)

J'ai fait un essai en suivant tes explications :

mysql_select_db($database_secure, $secure);
$query_rsmulhouse = $sql = "SELECT * FROM mulhouse ORDER BY alphabet"; 

 if (isset($_GET['etat']))
  $sql.= " WHERE etat_id_etat = ".GetSQLValueString($coletat_rsmulhouse, "text") ;


if (isset($_GET['budget']))
  $sql.= " AND budget_id_sbudget = ". GetSQLValueString($colbudget_rsmulhouse, "text") ;
  
  
  if (isset($_GET['secteur']))
  $sql.= " AND secteur_id_secteur = ". GetSQLValueString($colsecteur_rsmulhouse, "text") ;
  
  
if (isset($_GET['type']))
  $sql.= " AND type_id_type = ".GetSQLValueString($coltype_rsmulhouse, "text"); 
  
$rsmulhouse = mysql_query($query_rsmulhouse, $secure) or die(mysql_error());
$row_rsmulhouse = mysql_fetch_assoc($rsmulhouse);
$totalRows_rsmulhouse = mysql_num_rows($rsmulhouse);
Voilà donc ma requête.
Mon problème (si j'ai juste...) c'est que dans ma recherche, si je met le premier choix sur chaque liste ça marche, mais si je ne met qu'un ça ne m'affiche rien.
Comme au début.

Je dois donc avoir mal rempli...

Je dois rajouter des conditions dans les "if" suivant?
Par exemple, si la condition 1 n'est pas remplie, l'ignorer , et ainsi de suite?

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

27 mars 2008, 17:18

Y a un peu de ça... :)

Déjà, y a un p'tit soucis au niveau de ton ORDER BY, celui-ci ne devant figurer qu'à la fin de ta requête, donc après les WHERE/AND etc.

Autre petit soucis, tu utilises deux variables, la tienne ($query_rsmulhouse) et la mienne ($sql), va falloir trancher et n'en utiliser qu'une seule d'un bout à l'autre ;)

Enfin concernant le problème du WHERE/AND, il faut que le premier if() dans lequel php va rentrer ajoute un WHERE à la requête et les suivants un AND. Le problème, c'est qu'il peut très bien entrer dans le 2ème ou le 3ème sans passer par les premiers.

Pour cela, la solution la plus évidente est un "flag" qui dira si oui ou non le WHERE a déjà été utilisé. Tu peux ainsi par exemple définir la variable $isWhere=false et dans chacun de tes if() tester si celle-ci est vraie ou pas. Si elle est fausse, alors tu ajoute un "WHERE" et tu la passe à vrai, si elle est vraie, alors tu ajoutes juste un "AND" à la requête :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 18 Messages

27 mars 2008, 19:44

Merci pour cette rapidité :)

Alors si je comprends bien (c'est pas gagné!)

1/ Je définie la variable $isWhere=false. Je la met bien au dessus de mon mysql_select_db($database_secure, $secure); ?

2/ Dans chaque if j'intègre cette variable en disant si ma variable est "false" on ignore et passe de suite à la 2, et si ma variable is "true" on la prend en compte et on lui definit Where(ou AND) ... et on passe à la suivante.

Désolé si je pose des questions un peu "bête" mais je suis assez novice ...
Je suis encore loin du résultat ?

Merci d'avance, je m'y replonge

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

28 mars 2008, 09:41

T'es pas loin non, mais il ne faut pas "ignorer" la variable si elle est fausse. En effet, le fait qu'elle soit faut t'informe que le WHERE n'a pas encore été utilisé et qu'il te faut donc le mettre si tu ajoutes une condition. Sinon c'est un AND qu'il te faut :

Code : Tout sélectionner

SI un secteur a été spécifié ALORS SI ton flag est à faux ALORS complete la requête en ajoutant un WHERE et modifie le flag pour le mettre à vrai SINON complete la requête en ajoutant un AND puis complete la requête en ajoutant le filtre sur le secteur SI un budget a été spécifié ALORS SI ton flag est à faux ALORS complete la requête en ajoutant un WHERE et modifie le flag pour le mettre à vrai SINON complete la requête en ajoutant un AND puis complete la requête en ajoutant un filtre sur le budget ...
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 18 Messages

28 mars 2008, 10:34

Merci pour ces détails :)

Alors j'ai essayé pour la première liste, mais j'ai de gros problème de structure, avec les {} et les () et au niveau des ;

Voilà le code :

mysql_select_db($database_bdd, $bdd);

$isWhere=false;
$query_rsmulhouse = "SELECT * FROM mulhouse" ;
 
 if (isset($_GET['etat'])) // si un secteur est specifié
 	$query_rsmulhouse = // Alors
 		{	if ($isWhere=false;) // Si flag est faux
 			 $query_rsmulhouse = // Alors
			 "WHERE etat_id_etat = "; // complete requete avec WHERE
			 $isWhere=true // flag en true
 			}
  	elseif {
	 $query_rsmulhouse = // Alors
			  " WHERE etat_id_etat = ".GetSQLValueString($coletat_rsmulhouse, "text") ; // complete requete avec WHERE
	}


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

28 mars 2008, 11:22

Une instruction de type if(), ou même une boucle while(), for(), etc. porte uniquement sur l'instruction qui la suit immédiatement. Quand il n'y en a qu'une, pas de problème, mais lorsque c'est un bloc d'instructions qui est concerné, tu utilises les accolades :
if (isset($_GET['etat'])) // pour une seule instruction, les accolades ne sont pas nécessaire
  $coletat_rsmulhouse = $_GET['etat']; 

while ($row_rssecteur = mysql_fetch_assoc($rssecteur)) { // en revanche elles le sont pour un bloc d'instructions
  instruction1;
  instruction2;
  ...
}
M'enfin rien ne t'empêche d'en mettre à chaque fois, certains trouvent cela plus lisible, personnellement l'indentation me suffit :)

Par ailleurs, la commande elseif correspond à un SINON/SI et attends donc une seconde condition à tester.
if ($a) // SI $a est vrai
  ...
elseif ($b) // SINON ($a n'est pas vrai MAIS) SI $b est vrai
  ...
else // SINON (tous les cas précédent se sont avérés faux)
  ...
Dans ton cas, un simple else suffit puisque l'on veut juste tester si $isWhere est vrai ou pas :)

Enfin, l'opérateur de comparaison est "==". Si tu fais un "if ($isWhere=false;)" alors tu affectes la valeur false à ta variable avant de la tester, et donc le résultat sera toujours false :)

Ah et pis encore un détail, pour compléter une chaine en concaténant plusieurs élément à la suite, il te faut utiliser l'opérateur ".=", une fois encore si tu n'utilise que le "=" tu affectes la nouvelle valeur et écrase la précédente au lieu de la compléter :)
$isWhere=false; 
$query_rsmulhouse = "SELECT * FROM mulhouse" ; 
  
if (isset($_GET['etat'])) { // si un état est specifié 

  if ($isWhere==false) { // Si flag est faux 
    $query_rsmulhouse.= " WHERE "// Alors complete requete avec WHERE 
    $isWhere=true // flag en true (pour indiquer aux autres conditions qu'on a déjà utilisé le where)
  } 
  else { // Sinon (si le where a déjà été utilisé)
    $query_rsmulhouse.= " AND "// complete requete avec AND
  }

  $query_rsmulhouse.= " etat_id_etat = ".GetSQLValueString($coletat_rsmulhouse, "text") ; // complete requete avec la condition 

}

.... // tu recommances avec le secteur, le budget, etc.

$query_rsmulhouse.= " ORDER BY ... "; // ajoute la condition de tri à la fin 
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 18 Messages

28 mars 2008, 11:40

merci merci merciiiii
:priere: Tu me sauves ..

Par contre j'ai un petit problème
if ($isWhere==false) { // Si flag est faux  
    $query_rsmulhouse.= " WHERE "// Alors complete requete avec WHERE  
    $isWhere=true // flag en true (pour indiquer aux autres conditions qu'on a déjà utilisé le where) 
J'ai le message d'erreur : Parse error: syntax error, unexpected T_VARIABLE in .... qui correspond à
$isWhere=true
J'ai donc essayé :
$isWhere.=true
et
$isWhere==true
mais le message d'erreur est toujours présent.

Je me suis dit "et pourquoi pas définir la variable
$isWhere=true;
Mais forcément c'est faux ....

Faudrait il que je change les "false" et "true" en 0 et >0 ?

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

28 mars 2008, 11:44

Hum... tu viens effectivement de découvrir ce que l'on appel communément dans le jargon technique de php (mais également d'autres langage, c'est ça qu'est beau dans l'informatique, c'est universel) une..... boulette ! ;)

En effet, qu'est ce qu'on met à la fin des lignes de codes en php pour séparer les instructions et que j'ai lamentablement oublié sur ces deux lignes, provoquant inévitablement une erreur de syntaxe pour ce pauvre php ? ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 18 Messages

28 mars 2008, 11:52

La fermeture de la php ?> ?
Parce que chez moi c'est fermé ca à la fin j'ai :
<?php  ....
$query_rsmulhouse.= " ORDER BY alphabet ";

  
$rsmulhouse = mysql_query($query_rsmulhouse, $secure) or die(mysql_error());
$row_rsmulhouse = mysql_fetch_assoc($rsmulhouse);
$totalRows_rsmulhouse = mysql_num_rows($rsmulhouse);

?>
Non non pardon, je suis bête !!!! Biensur c'est les ";"
Niveau boulette j'en ai faite une grosse avec ce post !


[edit]


J'ai donc ajouté les ";" je n'ai plus d'erreurs, mais cela ne marche pas quand l'on choisit que l'un ou l'autre ...

Je mets le code complet, j'ai peut être mis trop? de ";" mais si je ne les mettait pas partout j'avais des erreurs avec les {}

mysql_select_db($database_secure, $secure);

$isWhere=false;
$query_rsmulhouse = "SELECT * FROM mulhouse" ;  
   
if (isset($_GET['etat'])) { // si un état est specifié  

  if ($isWhere==false) { // Si flag est faux  
    $query_rsmulhouse.= " WHERE ";// Alors complete requete avec WHERE  
    $isWhere=true ; // flag en true (pour indiquer aux autres conditions qu'on a déjà utilisé le where) 
  }  
  else { // Sinon (si le where a déjà été utilisé) 
    $query_rsmulhouse.= " AND ";// complete requete avec AND 
  } 

  $query_rsmulhouse.= " etat_id_etat = ".GetSQLValueString($coletat_rsmulhouse, "text") ; // complete requete avec la condition  

} 

if (isset($_GET['budget'])) { // si un état est specifié  

  if ($isWhere==false) { // Si flag est faux  
    $query_rsmulhouse.= " WHERE ";// Alors complete requete avec WHERE  
    $isWhere=true ;// flag en true (pour indiquer aux autres conditions qu'on a déjà utilisé le where) 
  }  
  else { // Sinon (si le where a déjà été utilisé) 
    $query_rsmulhouse.= " AND ";// complete requete avec AND 
  } 

  $query_rsmulhouse.= " budget_id_budget = ".GetSQLValueString($colbudget_rsmulhouse, "text") ; // complete requete avec la condition  

} 

if (isset($_GET['secteur'])) { // si un état est specifié  

  if ($isWhere==false) { // Si flag est faux  
    $query_rsmulhouse.= " WHERE ";// Alors complete requete avec WHERE  
    $isWhere=true ;// flag en true (pour indiquer aux autres conditions qu'on a déjà utilisé le where) 
  }  
  else { // Sinon (si le where a déjà été utilisé) 
    $query_rsmulhouse.= " AND ";// complete requete avec AND 
  } 

  $query_rsmulhouse.= " secteur_id_secteur = ".GetSQLValueString($colsecteur_rsmulhouse, "text") ; // complete requete avec la condition  

} 

if (isset($_GET['type'])) { // si un état est specifié  

  if ($isWhere==false) { // Si flag est faux  
    $query_rsmulhouse.= " WHERE ";// Alors complete requete avec WHERE  
    $isWhere=true; // flag en true (pour indiquer aux autres conditions qu'on a déjà utilisé le where) 
  }  
  else { // Sinon (si le where a déjà été utilisé) 
    $query_rsmulhouse.= " AND ";// complete requete avec AND 
  } 

  $query_rsmulhouse.= " type_id_type = ".GetSQLValueString($coltype_rsmulhouse, "text") ; // complete requete avec la condition  

} 

$query_rsmulhouse.= " ORDER BY alphabet ";

  
$rsmulhouse = mysql_query($query_rsmulhouse, $secure) or die(mysql_error());
$row_rsmulhouse = mysql_fetch_assoc($rsmulhouse);
$totalRows_rsmulhouse = mysql_num_rows($rsmulhouse);


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

28 mars 2008, 12:29

Alors c'était bien essayé, mais "Ca ne marche pas" c'est pas du jargon technique, contrairement à "boulette". Déjà, ça n'a pas de jambes, donc au mieux ça peut ne pas fonctionner, mais dans ce cas il y a :
- un résultat obtenu
- un résultat attendu
- un éventuel message d'erreur

Et là c'est technique ;)

Affiche la requête SQL que tu as généré avant de l'exécuter. Vérifies qu'elle est bien construites et que les valeurs sont bien renseignées (pis montre là nous tant qu'on y est). Essaye également de la jouer dans MySQL pour voir si elle retourne les résultats attendus :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...