Requete complexe selon variable(s) : WHERE AND

Invité
Invité n'ayant pas de compte PHPfrance

06 janv. 2011, 20:37

Bonjour,

Je développe actuellement un webservice qui renvoie une structure XML selon les arguments passé dans l’URL en GET.

Mon problème se situe au niveau de la construction de la requête qui va s’enrichir de WHERE et de AND selon les arguments passés. Il peut n’y avoir aucun argument comme il peut y en avoir 3.

Ma requête aurait donc la forme suivante :

SELECT * from table WHERE champ1=’$val_champ1’ AND champ2=’$val_champ2’ AND champ3=’$val_champ3’

Pour l’URL suivante appelé : http://www.monsite.com/webservice.php?c ... val_champ3

Comment organiser mon code PHP pour gérer la possible absence d’un argument ou d’un autre ?

En effet, et dans ce cas le WHERE peut ne pas etre présent. Je vois bien comment gérer par exemple l’absence d’argument « val_champ3 » mais comment gérér l’apparition d’un AND si un autre argument est présent ou d’un WHERE si le "val_champ3" est le seul appelé ?

Je pense que je pourrais m’en sortir avec des if mais couvrir l’ensemble des cas possibles me semble etre tentaculaire et une grande source d’erreur, et peu propre.

Auriez vous des conseils, des solutions ?

Et en espérant etre clair dnas mes explications...

Petit nouveau ! | 3 Messages

06 janv. 2011, 20:38

Je pensais être connecté... c'est moi qui ai posté ci dessus...

Eléphant du PHP | 288 Messages

06 janv. 2011, 23:28

Salut,

Tu pourrais par exemple faire un count sur $_GET si = 1 tu fais un where sans AND sinon tu boucles sur les valeurs dans le $_GET avec un foreach et tu construits ton where avec des AND

ViPHP
ViPHP | 2577 Messages

07 janv. 2011, 09:15

Bonjour,

Solution 1 :

Code : Tout sélectionner

SELECT * from table WHERE (champ1=’$val_champ1’ OR ’$val_champ1’ = ' ' ) AND (champ2=’$val_champ2’ OR ’$val_champ3’ = ' ') AND (champ3=’$val_champ3’ OR ’$val_champ3’ = ' ')
Solution 2 :

Code : Tout sélectionner

$SQL = 'SELECT * from table'; $operateur = ' WHERE '; if ($val_champ1<>'') { $SQL = $SQL + $OPERATEUR + "champ1=’$val_champ1’" $OPERATEUR = ' AND '; } if ($val_champ2<>'') { $SQL = $SQL + $OPERATEUR + "champ2=’$val_champ2’" $OPERATEUR = ' AND '; } if ($val_champ3<>'') { $SQL = $SQL + $OPERATEUR + "champ3=’$val_champ3’" }

Mammouth du PHP | 1967 Messages

07 janv. 2011, 09:50

Moi je testerais mes paramètres GET un par un, si il est rempli et VALIDE je l'ajoute dans un tableau sous la forme

Code : Tout sélectionner

champ2=’$val_champ2’
ensuite je fais un implode avec comme chaine de concaténation

Code : Tout sélectionner

AND
(espace devant et derrière)
et je test lors de la fabrication de la requéte si ma chaine n'est pas vide, dans ce cas j'ajoute WHERE .$maChaine

Si un jour tu devais passer à 56 arguments, ce code resterait valable et il suffirait d'ajouter des lignes de vérification de champs
De plus, tu sépare récupération et validation des paramètres de la construction de ta requète ce qui me semble pas mal du tout
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

07 janv. 2011, 11:25

La solution de Spols est la bonne ;)
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

Petit nouveau ! | 3 Messages

07 janv. 2011, 13:29

Merci pour votre aide. J'essai cela et je vous tiens au courant !!

Petit nouveau ! | 3 Messages

10 janv. 2011, 18:51

Salut,

J'ai donc essayé de mettre en œuvre la solution suggérée. Je me heurte à 2 soucis.

Je compte donc le nombre de GET valable afin d'ajuster ma requête. Si j'en ai 0 je ne mets pas de "WHERE + implode($array)"
Si j'en ai 1 ou plus, j'ajoute "WHERE + implode($array)"

Ma question porte sur la constitution de ce tableau... Peut-on automatiser la constitution de ce tableau ? Aujourd'hui je le dresse en tapant à la mano :

$array = array(champ1 LIKE ’$val_champ1’,champ2 LIKE ’$val_champ2’,champ3 LIKE ’$val_champ3’,champ4 LIKE ’$val_champ4’);

Mais comme tu disais Spols, devrais je faire de même s'il y en avait 56 ?

J'ai également une autre contrainte. Un des arguments est une date permettant la remontée des entrées > ou = à la date remontée. Dans ce cas il ne s'agirait donc pas d'un "LIKE " mais d'un ">=". Comment gérer cette exception ?

Mammouth du PHP | 1967 Messages

17 janv. 2011, 02:17

Il est important de vérifier les valeurs de tes champs, l'utilisateur peut y inclure ce qu'il veux.

je te préconiserais de commencer par instancier ton tableau.
$tableau = array();
ensuite pour chaque champs :récupère la valeur, vérifie la et protège la des requètes malhonnète
$varaible1 = (isset($_GET['variable1'])) ? $_GET['variable1'] : '';
$variable1 = check_value($variable1); //soit une fonction qui vérifie le contenu soit une exprèssion régulière
$variable1 = $variable1; //Ajouter ici les fonctions de protection des injection SQL (je ne connais pas cela par coeur)
if ($variable1 != '') $tableau[] = '`variable1` LIKE \''.$varaible1.'\'';
//Autre variable avec code du même type
$clause_where = implode(' AND ',$tableau);// voir si il ne faut pas tester que le tableau ne soit pas vide
$sql = 'SELECT * FROM table'
if ($clause_where ! = '') $sql .= ' WHERE '.$clause_where;
//suite du code
c'est un exemple de code, tu peux l'imaginer tout autrement.

Si tu veux l'automatiser un peu plus, il te faut catégoriser tes variables par rapport au types de données quelles contiennent (date, numéro de téléphone, nom, ...).

pour tes dates, remplace simplement le LIKE par l'opérateur que tu veux

PS, tes LIKE serait peut être plus éfficace comme ceci
if ($variable1 != '') $tableau[] = '`variable1` LIKE \'%'.$varaible1.'%\'';
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube