Problème de requêtes [TITRE MODERE CAR PEU EXPLICITE]

Signaler
Messages postés
103
Date d'inscription
dimanche 19 janvier 2003
Statut
Membre
Dernière intervention
19 septembre 2010
-
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
-
j'ai concu un site pour une agence immobiliere,
en cherchant un bien sur ma base de donnee en multi-critere. je fait ce qui suit :
j'ai un formulaire de plusieur champ, ce sont les critere de recherche :

type de bien : (appartement ou villa ou ....)
lieu : (paris ou lion ou ....)
prix minimal : 1 ou 2 ...
prix maximal : 9999999 ou 9999999999
suprefacie : 100m ou 200m ou ....

le problem que j'ai et quant un champ est vide.

alors je cherche en testant tout les champ :
si le champ type est remplee et lieu et prix min et prix max et superfacie son vide
alors je accede a la requete qui chere que le champ type

et

si le champ lieu est remplee et type et prix min et prix max et superfacie son vide
alors je accede a la requete qui chere que le champ lieu

je fait ces test et ca fait des enormes ligne de code.

je veux savoir svp es que cette methode est exacte ou il y a une methode oplimal qui peut m'eviter toutes ces lignes de code.
merci .

13 réponses

Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Hello,

le mieux aurait été de faire une fonction.
Tu mets tes champs à value="null" par défaut.
A la soumission, tu appelles la fonction qui crée la requête, en lui passant en paramètre tes différents $_POST.

Dans ta fonction, tu construits tes clauses WHERE (et éventuellement FROM) en fonction de la valeur des post.
Exemple à prendre avec des pincettes parce que c'est la copie de la méthode d'une des classes de mon projet actuel...C'est donc juste pour l'exemple :
function getList($comtId null, $entId null, $contId = null, $artId = null)
{
$whereClauseArr = array ();
if ($comtId !== null) {
$whereClauseArr[] = ' AND (sk.comt_id = '.$comtId.')';
}
if ($entId !== null) {
$whereClauseArr[] = ' AND (sk.ent_id = '.$entId.')';
}
if ($contId !== null) {
$whereClauseArr[] = ' AND (sk.cont_id = '.$contId.')';
}
if ($artId !== null) {
$whereClauseArr[] = ' AND (sk.art_id = '.$artId.')';
}
$sQuery = 'SELECT
sk.sk_id, rg.rg_libelle, zone.zone_libelle, etg.etg_libelle
FROM
stocks sk, sk_rangees rg, sk_zones zone, sk_etages etg
WHERE
(sk.rg_id = rg.rg_id) AND
(sk.zone_id = zone.zone_id) AND
(sk.etg_id = etg.etg_id)
';

foreach ($whereClauseArr as $qry) {
$sQuery .= $qry;
}
$sQuery .= ' ORDER BY
sk.rg_id, sk.zone_id, sk.etg_id';
$aTmp = array();
$this->oDB->query($sQuery);

while($a = $this->oDB->fetch_assoc() ) {
$aTmp[$a['sk_id']] = $a['rg_libelle'].$a['zone_libelle'].$a['etg_libelle'];
}
return $aTmp;
}
Messages postés
103
Date d'inscription
dimanche 19 janvier 2003
Statut
Membre
Dernière intervention
19 septembre 2010

Rechercher un bien par critère,
----

Type:,
<SELECT id=select5 name=typeID> <OPTION value="" selected>indifférent</OPTION> <OPTION value=Villa>Villa / Maison</OPTION> <OPTION value=Appartement>Appartement</OPTION> <OPTION value=Locale>Garage / Locale</OPTION> <OPTION value=Terrain>Terrain</OPTION></SELECT>,
----

Ville:,
<SELECT id=select6 name=villeID> <OPTION value="" selected>indifférent</OPTION> <OPTION value=Alger>Alger</OPTION> <OPTION value=anaba>anaba</OPTION> <OPTION value=oran>oran</OPTION> <OPTION value=constantine>constantine</OPTION> <OPTION value=setif>setif</OPTION> <OPTION value=bejaia>bejaia</OPTION></SELECT>,
----

Nbr de pièces: ,
<SELECT id=picesID name=picesID> <OPTION value="" selected>indifférent</OPTION> <OPTION value=Studio>Studio</OPTION> <OPTION value="2 Pieces">2 Pieces</OPTION> <OPTION value="3 Pieces">3 Pieces</OPTION> <OPTION value="4 Pieces">4 Pieces</OPTION> <OPTION value="5 Pieces et plus">5 Pieces et plus</OPTION></SELECT>,
----

Surface (m²) : ,
<TABLE width="100%">

----, mini </TD>
maxi
</TD></TR>
<TR>
<TD>Prix : </TD>
<TD>
mini ,
maxi
</TD></TR>
<TR>
<TD colSpan=2>


</TD></TR></TBODY></TABLE>

svp c tu veut me rendre service, par ce que je suis debutant en php et en sql
peut tu traduire ce que tu a ecrit au par avant (en haut) sur ce formulaire.
le nom des champ de haut en bas :
- type
- ville
- nbr pieces
- surfmin
- surrmax
- prixmin
- prixmax

merci pour ta reponce
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
Nan mais tu veux pas qu'on te le chie non plus ?
Messages postés
17
Date d'inscription
mardi 24 février 2004
Statut
Membre
Dernière intervention
8 janvier 2006

Lol, oui c'est un peu abusé je trouve, tu as juste a remplacer ohh :s
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
Juste pour toi Malalam au passage :)
"if ($comtId !null) {" Que c'est bien mocheuh :) En plus, tu ne testes même pas le type de ta variable si c'est différent de NULL ! Bon, j'en déduis que c'est tout sauf un objet, une ressource, ou alors un type NULL... donc de ce fait, pour tester une bonne fois pour toute> is_scalar() !

Donc : if ( is_scalar($comtId) ) { ... }
etc... Au moins comme ca, tu es assuré au pire :)

Pareil, pourquoi avoir fait ca sous forme de tableau pour tes requètes avec AND ?

$query_ext = '';
if ( is_scalar($comtId) ) { $query_ext .'AND (sk.comt_id '.$comtId.')';
}
// etc...
// et à la fin :
if ( !empty($query_ext) ) $sQuery .= $query_ext;

Voila, c'est qu'un conseil que je te donne, mais si c'est plus rapide ta facon, pourquoi pas :)
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
FhX => disons qu'on est 2 à bosser là-dessus, et que je dois m'adapter... ;-)
le getList est appelé explicitement, à partir de valeurs connues; le but est simplement de dire : si on passe NULL, on ne fait rien. Sinon, c'est qu'on a passé un entier (c'est epxlicite, comme je te l'ai dit, on sait ce qu'on aura toujours : un entier).
Maintenant, oui, is_scalar () est plus joli :-)
Quant au tableau, je ne défends pas : mes portions de code étaient avec une bête concaténation, en effet. Mais comme mon collègue a plus de mal à s'adapter à mon code, que moi au sien, j'ai laissé tomber et j'ai calqué son mode de fonctionnement.
Bref, non, je ne pense pas que ce soit plus rapide, bien au contraire.
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
J'ai remplacé is_scalar (), en tous cas dans mes portions de code...lol.
Je nepense pas qu'il ait des problèmes pour lire ça...quand même ;-)
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
oh quand même !! Sinon tu lui dis à quoi ca sert en commentaire :)

Par contre dis moi, si tu ne passes aucun argument dans ta méthode, quand tu fais un foreach, t'as pas une erreur du fait que ton tableau peut être vide ?
Messages postés
2350
Date d'inscription
mercredi 13 octobre 2004
Statut
Membre
Dernière intervention
18 avril 2015
3
Enfin moi je te dis ca comme ca, étant donnée que c'est une classe, et qu'une classe peut se faire hériter très vite, autant la faire la plus générique possible, et surtout la plus strict au niveau des valeurs qui viennent et qui repartent des méthodes :)
Messages postés
103
Date d'inscription
dimanche 19 janvier 2003
Statut
Membre
Dernière intervention
19 septembre 2010

en tous les cas ca donne un erreur

$ttype = null;
$tpices = null;
$tville = null;
$tsurfmin = null;
$tsurfmax = null;
$tprixmin = null;
$tprixmax = null;


if ($HTTP_POST_VARS['typeID'] !== null) { $ttype '(type '.$HTTP_POST_VARS['typeID'].')';
}
if ($HTTP_POST_VARS['picesID'] !== null) { $tpices ' AND (pices '.$HTTP_POST_VARS['picesID'].')';
}
if ($HTTP_POST_VARS['villeID'] !== null) { $tville ' AND (ville '.$HTTP_POST_VARS['villeID'].')';
}
if ($HTTP_POST_VARS['surfmin'] !== null) {
$tsurfmin = ' AND (surface >= '.$HTTP_POST_VARS['surfmin'].')';
}
if ($HTTP_POST_VARS['surfmax'] !== null) {
$tsurfmax = ' AND (surface <= '.$HTTP_POST_VARS['surfmax'].')';
}
if ($HTTP_POST_VARS['prixmin'] !== null) {
$tprixmin = ' AND (prix >= '.$HTTP_POST_VARS['prixmin'].')';
}
if ($HTTP_POST_VARS['prixmax'] !== null) {
$tprixmax = ' AND (prix <= '.$HTTP_POST_VARS['prixmax'].')';
}


$query_Reff = sprintf("SELECT * FROM bien WHERE $ttype.$tpices.$tville.$tsurfmin.$tsurfmax.$tprixmin.$tprixmax");
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Elle hérite déjà, en fait, d'une classe générique.
Mais bon, j'ai pas dit que j'appréciais cette façon de coder lol...seulement moi je suis ingénieur de dév, responsable de dév, certes, mais lui est le responsable informatique et code parce qu'il adore ça. Donc bon...

Ca donne quoi comme erreur ?
Messages postés
103
Date d'inscription
dimanche 19 janvier 2003
Statut
Membre
Dernière intervention
19 septembre 2010

Erreur de syntaxe près de '. AND (pices = ). AND (ville = ). AND (surface >= ). AND (surfac' à la ligne 1

je pence que le problem est due a la facon dant je concatine.
Messages postés
10840
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Tes '.' sont DANS ta requête, là.