IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

un moteur de recherche dans une base


Sujet :

PHP & Base de données

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 389
    Points : 192
    Points
    192
    Par défaut un moteur de recherche dans une base

    Je m'occupe d'une base de données clients, et il m'a été demandé d'ajouter un outil type moteur de recherche à cette appli.

    La recherche porte sur le nom du client ou sur le nom de sa société.
    Voilà comment j'ai procédé :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function rechercheMotCle($val){			
    $requete = 	"SELECT  * 
    			FROM    societe
        			INNER JOIN
           						testeur 
           						ON  NumSociete = SocieteTesteur
    			WHERE surListeNoire = 0
    			AND   NomSociete LIKE '%".$val."%'
        		OR   NomTesteur LIKE '%".$val."%' 
    			ORDER BY NomSociete ASC ";
    return $requete;
     
    	}


    Ca marche bien, mais je voudrais lui apporter une amélioration : permettre, lors de la saisie par l'utilisateur, que l'espace "coupe" la chaine en deux, pour pouvoir traiter chaque mot séparément avec la fonction.

    Comment faire?

  2. #2
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 464
    Points : 4 646
    Points
    4 646
    Par défaut
    salut
    avec la fonction explode(), tu peux separer les elements, une boucle pour appeller ta fonction et le tour est joue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $texte='test retest';
    foreach(explode(" ",$texte) as $valeure)
    {
    rechercheMotCle($valeure);
    }
    ps : pour l'exemple, j'ai mis le texte en brut dans $texte.. a toi d'adapter.
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 389
    Points : 192
    Points
    192
    Par défaut
    Merci, je pense que je peux traiter ça avec la fonction explode().

    Comme j'envoie le texte avec un formulaire, je dois appliquer le explode() au $_POST['text'] alors?

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 389
    Points : 192
    Points
    192
    Par défaut
    en fait, j'ai modifié le code dans ma fonction, c'est bien plus simple et ça m'a évité de faire des modifications partout dans le code (là ou je traitai $requete, puisque je me retrouvai avec un tableau de requetes + dur à gérer).

    Je poste le code de la fonction, peut être qu'elle sera utile à certains même si je suis sur qu'on peut faire bien mieux.

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    /*recherche dans deux tables si la chaine de mots est présente en découpant chaque mot séparé par un espace.
    retourne une chaine qui doit être taitée avec un ordre du type mysql_query()*/
    function rechercheMotCle($val){
    	$requete = 	"SELECT  * 
    				FROM    societe
        				INNER JOIN
            					testeur 
            					ON  NumSociete = SocieteTesteur
    				WHERE surListeNoire = 0 ";
    		foreach(explode(" ",$val) as $mot) {
    		$requete.=" AND   NomSociete LIKE '%".$mot."%' ";
    	}
     
    	foreach(explode(" ",$val) as $mot) {
    		$requete.=" OR   NomTesteur LIKE '%".$mot."%' ";
    	}
    	$requete .= " ORDER BY NomSociete ASC ";
    	return $requete;
    }

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 21
    Points : 25
    Points
    25
    Par défaut
    Salut,

    je pense que tu as bien fait de mettre le explode directement dans ta fonction sa évite une surcharge de la bdd en ne faisant qu'une requete par recherche et pas une requete par mot.

    Par contre je ne suis pas sur que qu'avec ta nouvelle fonction tu obtienne la requete que tu veux. En effet si tu fais une recherche sur "mot1 mot2 mot 3" par exemple, avec ta fonction ta requete sera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT * FROM ... 
    WHERE surListeNoire = 0 AND NomSociete LIKE "%mot1%" 
    AND NomSociete LIKE "%mot2" AND Nomsociete LIKE "%mot3%" 
    OR NomTesteur LIKE "%mot1" OR NomTesteur LIKE "%mot2%" 
    OR NomTesteur LIKE "%mot3"
    ce qui veut dire que pour apparaitre en resultat il faut que NomSociete contienne mot1 ET mot2 et que soit nomSociete contienne mot3 soit que NomTesteur contienne un des 3 mots

    ce qui fait une condition un peu bizarre et ne correspond pas à la logique de ta première requete.

    Quel resultat veux tu obtenir?
    - NomSociete contient tous les mots ET/OU nomTesteur contient tous les mots
    - NomSociete contient au moins un mot recherché ET/OU nomTesteur contient au moins un mot recherché

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 389
    Points : 192
    Points
    192
    Par défaut
    En fait, j'ai encore modifié la fonction, mais là encore, je pense qu'il y a une erreur...

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    function rechercheMotCle($val){
    	$requete = 	"SELECT  * 
    				FROM    societe
        				INNER JOIN
            						testeur 
            						ON  NumSociete = SocieteTesteur
    				WHERE surListeNoire = 0 ";
    	foreach(explode(" ",$val) as $mot) {
    		$requete.=" AND   NomSociete LIKE '%".$mot."%' ";
    	}
     
    	foreach(explode(" ",$val) as $mot) {
    		$requete.=" OR   NomTesteur LIKE '%".$mot."%' ";
    	}
     
    	$requete .= " ORDER BY NomSociete ASC ";
    	return $requete;
    }

    Ce que je veux, en fait, c'est que la fonction cherche si on tape par exemple
    "dev com", on trouve quand même developpez.com, en premier résultat. (qu'il puisse y avoir une chaine différente au milieu).
    La recherche s'effectue à la fois sur le nom du testeur et sur le nom de la société, mais il n'y a pas de lien entre eux dans la recherche.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 21
    Points : 25
    Points
    25
    Par défaut
    tu as toujours la meme erreur qui vient du fait que tu utilises un AND dans ta boucle foreach sur NomSociete et un OR pour NomTesteur.

    Ensuite si tu veux faire apparaître en premier les résultats exacts en ensuite les résultats partiels ca se complique. Tu dois utiliser deux requetes, la premiere qui recherche les résultats exacts (NomSociete ou NomTesteur contient tous les mots) puis une autre qui recherches les resultats partiels (NomSociete ou NomTesteur contient au moins un mot) mais il faut exclure les resultats exacts...

    Pour avoir les résultats exactes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    $mots = explode(" ", $val);
     
    for ($i = 0; $i < count($mots; $i++) {
                     if ($i == 0) {
    	             	$req_soc =" AND (NomSociete LIKE '%".$mots[$i]."%' ";
                              $req_test = " OR (NomTesteur LIKE '%".$mots[$i]."%' ";
                     }	
                     elseif ($i == count($mots) -1) {
                              $req_soc.=" AND   NomSociete LIKE '%".$mots[$i]."%') ";
                              $req_test.=" AND   NomTesteur LIKE '%".$mots[$i]."%') ";
                     }
                     else {
                              $req_soc.=" AND   NomSociete LIKE '%".$mots[$i]."%' ";
                              $req_test.=" AND   NomTesteur LIKE '%".$mots[$i]."%' ";
                     }
     
    }
     
    $requete .= $req_soc.$req_test;
    Ensuite pour les résultats partiels tu refais la meme chose en remplaçant les AND par des OR (sauf le premier AND).

    Mais attention il faudra qu'avant d afficher les résultats de la deuxième requete tu vérifie qu'ils n'aient pas déjà été affichés suite à la première requète.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2009
    Messages : 389
    Points : 192
    Points
    192
    Par défaut
    Merci beaucoup! En plus, les résultats exacts suffiront, ça sera plus clair pour l'utilisateur, plutôt que d'avoir une grande liste avec des résultats qui se rapprochent, puisque ce qui compte c'est le nom, on s'en fiche d'avoir monsieur lamartine si on cherche monsieur martin!

    Mais dans ton code, tu utilise deux requetes (req_soc et req_test) ça risque de me poser des problèmes pour mettre ça en place dans le code, car partout ou j'appelle la fonction (et utilise $requete), il n'y a bien qu'une seule requête.

    C'est possible de faire autrement? Sinon, tant pis, j'y passerai du temps!

    edit: Pardon, je viens de relire et j'ai vu que tu concaténai les deux requêtes en une après...

    Merci beaucoup, je mets ça en place!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 29/08/2011, 15h03
  2. [MySQL] Moteur de Recherche dans une base mysql
    Par nostalamigo dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 14/04/2009, 22h33
  3. Recherche dans une base de donnée
    Par genova dans le forum SQLite
    Réponses: 8
    Dernier message: 28/09/2005, 23h16
  4. problème de recherche dans une base de données
    Par bouzid_mehdi dans le forum Bases de données
    Réponses: 2
    Dernier message: 19/07/2005, 06h47
  5. recherche dans une base de donnée+boucle
    Par eric205 dans le forum Bases de données
    Réponses: 8
    Dernier message: 15/03/2005, 21h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo