Moteur de recherche (PHP) dans une base (SQL)

Nous allons voir ici le principe de base d'un moteur de recherche dans une base de données (sql).

* Notez que ce tuto est compatible avec php < 4.2 , vous saurez modifier les scripts en fonction de votre version php.
je vous rappelle juste que les variables provenant d'un formulaire en métode 'post', se récupèreront à partir de php > 4.2 de la forme suivante $_POST['variable'] et non plus $variable.



  • 1- Recherche sur un mot.

  • On commence donc par un petit échauffement.
    Vous voulez un petit moteur de recherche pour interroger votre base sur une table précise.

    Commençons par le formulaire (tout simple):
    Formulaire
      

    Code du formulaire:
    <form method="POST" action="resultat.php">
    <input type="text" name="mot" size="20">&nbsp;&nbsp;<input type="submit" value="Rechercher">
    </form>
    Jusque là, vraiment rien de nouveau ni rien de compliqué !

    Traitement du formulaire /requête /résultats :
    Nous allons tout d'abord imaginer une table, celle de vos amis et contacts.
    Nous la nommons donc contact et se caractérise ainsi:
    Exemple de la table contact :
    id (auto_increment) noms (varchar) adresse (varchar) ville(varchar) phone (varchar ou int)

    Revenons donc à notre petit moteur de recherche, nous souhaitons l'utilser pour trouver le nom d'un de nos contacts ou amis.

    Script pour la recherche et affichage des résultats:
    <?
    if(empty($mot)){
    header('Location:pageformulaire.php');
    exit;
    }
    else{

    $db = mysql_connect('localhost', 'login', 'password') or die('<font color=red>Désolé mais vous ne pouvez voir les infos de la data-base</font>');
    mysql_select_db('nomdelabase',$db);

    $query="Select * from contact where noms like '$mot'" ;
    $result = mysql_query( $query )or exit ('Erreur SQL !'.$query.'<br>'.mysql_error());
    while($data = mysql_fetch_array($result))
    {
    if(empty($data['noms'])){
    echo"Désolé pas de résultat";
    }
    else
    {
    echo"Nom : ".$data['noms']."&nbsp;&nbsp;Adresse:".$data['adresse']."&nbsp;&nbsp; Ville:".$data['ville']."&nbsp;&nbsp;Tél.:".$data['phone']."<br>";
    }
    }
    mysql_close();
    }
    ?>

    Explications:
    Nous avons tout d'abord effectué une première vérification pour bien s'assurer que l'internaute n'a pas cliqué sur rechercher par erreur avec une variable vide.
    Dans ce cas, on le renvoit sur la page initiale, et on met un exit de sécurité.
    Puis nous allons interroger notre table contact pour savoir si le mot rechercher existe dans la colonne noms de cette table.
    Nous utilisons la syntaxe like (= « comme » en anglais) plus appropriée à cette recherche puisque nous travaillons sur des caractères et non pas sur des nombres.
    Nous allons enfin afficher la ou les réponses, sans oublier de prévoir le cas de réponse nulle, donc un petit message indiquant: « Désolé pas de résultat ».
    Nous terminons par la fermeture de la boucle et n'oublions pas de fermer la connexion.
    Nous aurions pu élargir la même recherche sur les 2 autres colonnes (adresse,ville) de la table, en modifiant la requête de la façon suivante:

    $query="Select * from contact where noms like '$mot' or adresse like '$mot' or ville like '$mot'" ;


  • 2- Recherche sur plusieurs mots.

  • Les moteurs de recherche sont rarement sur un mot mais acceptent plusieurs mots.
    Comment faire exactement ?
    Nous partons sur un autre exemple de situation et de table.
    Situation, rechercher sur un forum un sujet qui regroupent tous les mots.

    Exemple (vraiment bidon) de la table forum :
    id (auto_increment) date (datetime) titre (varchar) sujet(lontext) pseudo (varchar)

    Ici en encore, plusieurs possibilités:
    - rechercher sur titre ou sujet qu'un des mots ou que tous les mots y soient.
    - rechercher sur titre et sujet qu'un des mots ou que tous les mots y soient.


    Script de recherche sur plusieurs mots:
    //remplacement des espaces par des +
    $mot= str_replace(" ","+",$mot);
    //formatage des mots clef
    $mot = StripSlashes(trim($mot));

    //on va mettre en tableau la chaîne selon le séparateur indiqué (ici +)
    $mot=explode("+",$mot);
    $nb=sizeof($mot);//nombre de mots clés
    if( $nb>0 ){//s'il y a + d'1 mot clé
    ##################### Fin de la partie commune ###########################

    //Recherche sur "titre" (exemple) qu'au moins un des mots y soient:
    $message="Select * from table where 0 ";
    for($i=0 ;$i<$nb ;$i++ ){// boucle pour les mots clés
    $joint[$i]="OR titre like '%".$mot[$i]."%' ";
    } foreach ($joint as $value)
    {//on finit la requête
    $message.=$value;
    }//Fermeture boucle1
    echo$message;// la requête au complet !!
    }

    //Recherche sur "titre" et "sujet" qu'au moins un des mots y soient:
    $message="Select * from table where 0 ";
    for($i=0 ;$i<$nb ;$i++ ){// boucle pour les mots clés
    $joint[$i]="OR titre like '%".$mot[$i]."%' ";
    $joint2[$i]="OR sujet like '%".$mot[$i]."%' ";
    } foreach ($joint as $value)
    {//on finit la requête
    $message.=$value;
    }//Fermeture boucle1
    foreach ($joint2 as $valeur)
    {//on finit la requête
    $message.=$valeur;
    } echo$message;// Si vous désirez lire la requête au complet !!
    }

    //Recherche sur "titre" (exemple) que tous les mots y soient:
    $message="Select * from table where 0 or ";
    for($i=0 ;$i<$nb-1 ;$i++ ){//boucle pour le And
    $suivant[$i]="AND";
    } for($i=0 ;$i<$nb ;$i++ ){// boucle pour les mots clés
    $joint[$i]=" titre like '%".$mot[$i]."%' ".$suivant[$i]." ";
    }
    foreach ($joint as $value)
    {//on finit la requête
    $message.=$value; }//Fermeture boucle1
    echo$message;// si vous désirez lire la requête au complet !!
    }

    //Recherche sur "titre" et sujet que tous les mots y soient:
    $message="Select * from table where 0 or ";
    for($i=0 ;$i<$nb-1 ;$i++ ){//boucle pour le And
    $suivant[$i]="AND";
    } for($i=0 ;$i<$nb ;$i++ ){// boucle pour les mots clés
    $joint[$i]=" titre like '%".$mot[$i]."%' ".$suivant[$i]." ";
    }
    foreach ($joint as $value)
    {//on finit la requête
    $message.=$value; }//Fermeture boucle1
    $message.="OR"; for($i=0 ;$i<$nb ;$i++ ){// boucle pour les mots clés
    $joint[$i]=" sujet like '%".$mot[$i]."%' ".$suivant[$i]." ";
    }
    foreach ($joint as $valeur)
    {//on finit la requête
    $message.=$valeur; }//
    echo$message;// si vous désirez lire la requête au complet !!
    }



    Note : Vous pouvez tester ces scripts pour en voir les différentes requêtes qu'ils génèrent:
    Créer une page php, créez une variable $mot avec 1,2 ou 3 mots séparés par un espace puis faites des copier coller du script pour avoir le résultat.

    Explications :
    Pour comprendre aisement ces scripts, il vous faut maîtriser quelques éléments comme:
    - Les tableaux (array) et l'utilisation des boucles pour les décortiquer.
    - La concaténation pour créer la requête finale.
    - Syntaxe mysql basique .

    En effet nous avons passé par des tableaux et ensuite des boucles toutes les possibilités de choix pour la requête puis nous avons réuni grâce à la concaténation les différentes valeurs retounéés par les boucles.
    Les scripts n'incluent pas la connexion à la base et la requête comme telle, mais, là ce serait vraiment trop vous macher le travail !!

  • 3- Recherche avec plusieurs mots et une table en variable.

  • Prenons le cas d'un forum découpé en plusieurs thèmes, chacun de ses thèmes ayant une table différente dans la base, vous aurez à utiliser dans votre requête finale, une variable.
    Jusque là pas vraiment de problème, et si vous vouliez chercher sur plusieurs tables, vous pourrez toujours les passer en tableau à nouveau.
    Mais imaginons que ce moteur vous serve pour chercher sur n'importe quelle table dont vous ne connaissez pas forcemment sa structure ! Là çà se complique... et pourtant, voici une méthode pour obtenir le résultat.

    Script recherche :
    $mot= str_replace(" ","+",$mot);
    //formatage des mots clef
    $mot = StripSlashes(trim($mot));

    $db = mysql_connect('localhost', 'login', 'pass');
    mysql_select_db('base',$db);
    $sql="Select * from $table ";
    $req = mysql_query($sql);
    $nbre = mysql_num_fields($req);
    $mot=explode("+",$mot);
    $nb=sizeof($mot);
    if( $nb>0 ){//s'il y au moins 1 mot clé
    //début de la requête
    $message="Select * from table where 0 "; $a=0; while($a<$nbre){//boucle 1 pour les différentes colonnes de la table
    $champ = mysql_field_name($req,$a++);
    for($i=0 ;$i<$nb ;$i++ ){//2nde boucle pour les mots clés
    $joint[$i]="OR ".$champ."like '%".$motsclef[$i]."%' ";
    } foreach ($joint as $value)
    {//on finit la requête
    $message.=$value;
    }//Fermeture boucle1
    }//Fermeture boucle2
    echo$message;// pour afficher la requête au complet !!
    }

    Explications :
    Nous allons une fois de plus utiliser une boucle pour lire toutes les colonnes de la table choisie en variable.
    Pour cela, nous utiliserons la fonction :
    - mysql_num_fields(requête) qui retourne le nombre de colonnes de la requête.
    - mysql_field_name(requete,n°decolonne) retourne le nom d'une colonne. Dans l'exemple nous avons considéré de chercher qu'il y ait au moins un des mots dans une des colonnes. A partir des scripts précédents vous pourrez créer les conditions que vous désirez pour cette recherche.
    NB.: Danger de cette méthode, vous interrogez toutes vos colonnes, même celle qui ne sont pas attribuées initialement à l'affichage (exemple l'id de l'enregistrement).
    Vous devez donc jouer sur la position de colonnes sensibles pour faire les ajustements dans:
    $a=0; while($a<$nbre){
    $champ = mysql_field_name($req,$a++);
    Exemple:
    Si id est toujours votre première colonne demarrez $a = 1;

    Utilisez donc ce script avec toutes les sécurités possibles.



    Si des doutes persistent, des questions spécifiques, des petits problèmes de mise en place, n'hésitez pas à consulter le forum référence en php :
    www.AllHtml.com

    Tutos:
    Cases à cocher   Tronquer un texte    Moteur de recherche    Tableau (Array) et boucles    Caddie virtuel    Calendrier   

    Notes:
    Notez que de toute façon ces scripts ne sont qu'à titre d'exemples et n'en sont donc que trés partiels, il vous faudra bien-sûr les intégrer dans l'environnement de votre page, de votre site, mais la méthode est là et elle fonctionne.
    Autre point important, ces morceaux de scripts notament, lorsqu'il y a connexion à votre base de données, ne font aucune référence à certains problèmes de sécurité.