Général

Les PCRE

Les POSIX

Pratique

Linux

Spécial php

Les billets de fred

Requêtes dynamiques et Moteur de recherche !

Cet article va vous montrer comment construire dynamiquement vos requêtes pour vos systèmes de recherches

Qu'appelle t'on une requête dynamique ?

On appelle requête dynamique est une requête construite à la volée par votre script.
Vous avez déjà tous vu ou même codé des requêtes de ce genre :


<?php
$req="SELECT * FROM matable WHERE champ1=$valeur1 AND champ2=$valeur2 AND champ3=$valeur3 AND champ4=$valeur4 order by id asc")
?>


C'est bien, mais c'est long à écrire, cela oblige le posteur à remplir tous les champs car si un seul champ est vide la requête ne va plus fonctionner. L'idéal serait de pourvoir prévoir en fonction des éléments du formulaire.

J'en entends déjà dire : "ouais on va devoir utiliser des conditions à tour de bras, préfabriquer 36 requêtes, mettre des if partout, ça va être vraiment déguelasse."

Et bien non, il y a moyen de contruire cela de manière dynamique, sans devoir prévoir toutes les combinaisons possibles.

C'est parti, je vous montre avec le petit script suivant :

<?php
if(!empty($_POST)){
if(empty($_POST['mot1']) && empty($_POST['mot2']) && empty($_POST['mot3'])){
echo 'Veuillez au moins remplir un champ de recherche<br /><br />
<a href="javascript:history.go(-1);">Retour au formulaire</a>';
}
else
{
    $req = "select leschamps from latable where";
    $req.=(!empty($_POST['mot1'])) ? " champ1='".$_POST['mot1']."' AND":"";
    $req.=(!empty($_POST['mot2'])) ? " champ2='".$_POST['mot2']."' AND":"";
    $req.=(!empty($_POST['mot3'])) ? " champ3='".$_POST['mot3']."' AND":"";
    $req= rtrim($req,' AND');
   
$req.=" order by bidule asc";
echo $req;
}
}
else
{
echo '<form method="post" action="',$_ENV['PHP_SELF'],'">
Mot 1 :<input type="text" name="mot1" size="25"><br /><br />
Mot 2 :<input type="text" name="mot2" size="25"><br /><br />
Mot 3 :<input type="text" name="mot3" size="25"><br /><br />
<input type="submit" value="valider">
</form>';
}
?>

Explication :
Sur une même page de test, notre petit formulaire et la construction de notre requête dynamique.

Grâce à la première fonction !empty() que vous connaissez tous, on vérifie que notre formulaire est bien soumis. La seconde ligne !empty vérifie qu'au moins un champ de notre formulaire est rempli ce qui semble logique pour ne pas réaliser une recherche dans du vide !
On a d'ailleurs un lien qui permet de revenir au formulaire pour le corriger ou le complèter.

Si au moins un champ est rempli, on passe dans le else et la requête est construite à la volée.
J'ai utiliser l'opérateur ternaire Opérateur ternaire

A partir de là, je vous laisse regarder les 3 lignes de code et faire le test pour visualiser la requête.

La dernière ligne vraiment intéressante est celle avec le rtrim qui permet de zapper le AND juste avant le order by.

Et voilà, votre première requête dynamique.
Tout ça c'est bien me direz-vous, mais moi j'ai 10 champs ou 10 listes de sélection et ça va faire long de taper mes 10 !empty() et mes 10 instructions ternaires.

Ho là, stop, arrêtez de râler et réfléchissez un peu !
Que pourrait-on faire pour éviter la répétion de nos conditions de vérifications ?
Quoi ? Qui a murmuré une boucle là dans le fond ?

Et oui, on va traiter nos possibilités dans une boucle... avec foreach() et automatiser la totalité de la requête dynamique. Champs et valeurs seront intégrés à la requête uniquement s'ils ont été utilisé dans le formulaire.

Et voilà la bête :

<?php
if(!empty($_POST))
{
$req = 'SELECT les_champs FROM latable WHERE';
foreach($_POST as $key=>$val)
{
$verif=trim($val);
    if(!empty($verif))
    {
    $req.= ' '.$key.'="'.$verif.'" AND' ;
    }
}
    $req = rtrim($req,' AND');
    $req.=' order by truc asc';
    echo $req;
}
else
{
echo '<form method="post" action="',$_ENV['PHP_SELF'],'">
Mot 1 :<input type="text" name="mot1" size="25"><br /><br />
Mot 2 :<input type="text" name="mot2" size="25"><br /><br />
Mot 3 :<input type="text" name="mot3" size="25"><br /><br />
<input type="submit" value="valider">
</form>';
}
?>

Imaginez le même avec des listes de selection

Gardez le même code mais remplacez simplement le formulaire comme ceci :
<?php
echo '<form method="post" action="',$_ENV['PHP_SELF'],'">
Liste 1 :
<select name="liste1">
<option value="liste1-option1">Option 1</option>
<option value="liste1-option2">Option 2</option>
<option value="liste1-option3">Option 3</option>
</select>
Liste 2 :
<select name="liste2">
<option value="liste2-option1">Option 1</option>
<option value="liste2-option2">Option 2</option>
<option value="liste2-option3">Option 3</option>
</select>
Liste 3 :
<select name="liste3" >
<option value="liste3-option1">Option 1</option>
<option value="liste3-option2">Option 2</option>
<option value="liste3-option3">Option 3</option>
</select>
<input type="submit" value="valider">
</form>';
?>


Et voilà, ça fonctionne parfaitement !
Quoi, on murmure là dans le fond... qui rouspète là derrière ? C'est moi M'sieur... l'emmerdeur de service ! Et si j'ai des listes à sélection multiple, hein... on fait comment ?

Non mais vous avez décidé de me tuer sur ce coup. Je rappelle quand même, qu'en cette fin de juillet 2006, il ne fait pas moins de 37° à l'ombre, je crève de chaud, je crève de soif et la clim tourne à fond les manettes. smiley tire la langue

Bon, je suis gentil on va la faire avec nos trois listes du dessus :

<?php
if(!empty($_POST))
{
$req = 'SELECT les_champs FROM latable WHERE';
foreach($_POST as $keyliste=>$liste)
{
if(is_array($liste) && count($liste)>0)
foreach($liste as $val)
{
$verif=trim($val);
    if(!empty($verif))
    {
    $req.= ' '.$keyliste.'="'.$verif.'" OR' ;
    }
}
$req = rtrim($req,' OR');
$req.=' AND' ;
}
$req = rtrim($req,' AND');
    $req.=' order by truc asc';
    echo $req;
}
else
{
echo '<form method="post" action="',$_ENV['PHP_SELF'],'">
Liste 1 :
<select name="liste1[]" multiple>
<option value="liste1-option1">Option 1</option>
<option value="liste1-option2">Option 2</option>
<option value="liste1-option3">Option 3</option>
</select>
Liste 2 :
<select name="liste2[]" multiple>
<option value="liste2-option1">Option 1</option>
<option value="liste2-option2">Option 2</option>
<option value="liste2-option3">Option 3</option>
</select>
Liste 3 :
<select name="liste3[]" multiple>
<option value="liste3-option1">Option 1</option>
<option value="liste3-option2">Option 2</option>
<option value="liste3-option3">Option 3</option>
</select>
<input type="submit" value="valider">
</form>';
}
?>


Et voilà le travail !
Cela devrait normalement roulé tout seul si je n'ai pas fait de fautes dans mon code.
Je pense avoir fait le tour du sujet... pour le reste maintenant, c'est à vous de le faire et notamment tout ce qui touche à la sécurité du script et des données transittant via formulaire !
Mais bon, je ne dois pas vous le dire, hein, vous connaissez !
ADAM Benjamin 2008 | Admin