Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zér0 > Les tutoriels > Non-Officiels > Site Web > PHP > Points particuliers > Lecture du tutoriel

Un moteur de recherche par mots clés

Avatar
Auteur : dark-link
Créé : le 11/07/2007 17:46:50
Modifié : le 01/02/2008 10:32:43
Noter et commenter ce tutoriel
Imprimer ce tutoriel
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Bonjour. :)

Dans ce tutoriel, nous allons voir comment réaliser un moteur de recherche avec plusieurs options, en utilisant le critère de sélection LIKE.
Notre but sera d'en faire un qui permette plusieurs modes de recherche :

Je vous conseille vivement de lire ce tutoriel si vous n'avez jamais entendu parler du critère de sélection LIKE.

En avant. :D
Sommaire du chapitre :

Comment procéder

Rappel



Tout d'abord, nous ferons notre recherche dans une base de données puisque LIKE s'utilise dans une requête SQL.
Voici une requête permettant une recherche avec le critère de sélection LIKE.
Code : SQL
1
SELECT * FROM matable WHERE monchamp LIKE '%recherche%' ORDER BY id


Un problème



Oui, la recherche fonctionne, mais avec une requête comme celle-ci, vous allez rechercher dans votre table l'expression exacte qu'a entré le visiteur dans le formulaire de recherche. :(
Cela veut dire que la recherche ne se fait pas par mots clés.

Par exemple, supposons qu'un champ de votre table contienne "J'ai une voiture dans mon garage." . Si vous entrez les deux mots principaux de cette phrase dans votre recherche, à savoir "voiture garage", la requête ci-dessus va sélectionner toutes les entrées dont le champ de la table contient "voiture garage" . Hélas, il n'y aura bien sûr aucun résultat. Ce n'est donc pas très performant.

Mais réjouissez-vous. :D
Nous allons voir tout de suite comment faire un moteur de recherche permettant l'utilisation de mots clés.
Nous laisserons le visiteur choisir parmi les trois modes de recherche vus dans l'introduction.

Séparer les mots



Pour commencer, il faut "découper" la recherche du visiteur pour en séparer les mots.
Pour cela, nous allons utiliser une fonction : explode.
Voici un exemple montrant comment l'utiliser :
Code : PHP
1
2
3
4
5
$recherche = "voiture garage"; //la recherche
$mots = explode(" ", $recherche); //séparation des mots tous les espaces grâce à explode
$nombre_mots = count($mots); //$nombre_mots = 2
echo $mots[0]; //$mot[0] = voiture
echo $mots[1]; //$mot[1] = garage

Avec ce code, nous allons séparer les mots de la recherche à chaque espace. Et nous allons ensuite compter le nombre de mots. Nous verrons plus tard qu'avoir le nombre de mots est indispensable. :-°


La requête



Maintenant, occupons-nous de la requête. Il faudra utiliser plusieurs LIKE si nous voulons faire une recherche par mots clés.
Voici un exemple de requête avec deux LIKE :
Code : SQL
1
SELECT * FROM matable WHERE monchamp LIKE '%motcle1%' AND monchamp LIKE '%motcle2%' ORDER BY id

Il faut toujours mettre le nom du champ dans lequel on fait la recherche avant LIKE.
On aurait très bien pu mettre OR à la place de AND. Ainsi, on aurait sélectionné toutes les entrées dont le champ contient au moins un des deux mots clés. ^^


Utilisation des mots dans la requête



Mais comment je fais pour utiliser les mots clés dans ma requête, moi ? :euh:

Nous allons utiliser une boucle. Grâce à elle, nous allons créer une variable contenant une partie de la requête SQL. Uniquement ce qui concerne LIKE, en fait.
C'est là que le nombre de mots de la recherche va nous être utile. Grâce à ce nombre, nous pourrons arrêter la boucle dès que tous les mots de la recherche y seront passés.
Voici la boucle que nous utiliserions dans notre exemple :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$recherche = 'voiture garage';
$mots = explode(' ', $recherche); //séparation des mots de la recherche à chaque espace
$nombre_mots = count ($mots); //compte le nombre de mots
 
$valeur_requete = '';
for($nombre_mots_boucle = 0; $nombre_mots_boucle < $nombre_mots; $nombre_mots_boucle++) //tant que le nombre de mots de la recherche est supérieur à celui de la boucle, on continue en augmentant la variable $nombre_mots_boucle de 1 à chaque fois
{
$valeur_requete .= 'AND monchamp LIKE \'%' . $mots[$nombre_mots_boucle] . '%\''; //modification de la variable $valeur_requete
}
$valeur_requete = ltrim($valeur_requete,'AND'); //suppression de AND au début de la boucle

J'ai utilisé la fonction ltrim, car au début de l'utilisation de LIKE dans une requête il n'y a pas de AND ou de OR. ;)


Avec cette boucle, $valeur_requete a pour valeur :
Code : SQL
1
monchamp LIKE '%voiture%' AND monchamp LIKE '%garage%'

Il suffit ensuite d'insérer $valeur_requete dans la requête et le tour est joué. Ce qui donne ceci :
Code : SQL
1
SELECT * FROM matable WHERE $valeur_requete ORDER BY id

Si on remplace $valeur_requete par sa valeur, alors la requête donne ceci :
Code : SQL
1
SELECT * FROM matable WHERE monchamp LIKE '%voiture%' AND monchamp LIKE '%garage%' ORDER BY id

Voilà, nous avons notre requête.
Il ne vous reste plus qu'à afficher les entrées sélectionnées. ;)


Différents modes de recherche



Comme je l'ai dit en introduction, notre moteur de recherche doit permettre trois modes de recherche.
Pour cela, vous devez permettre aux visiteurs de choisir entre les trois modes possibles dans le formulaire de recherche.
Ensuite, une fois le formulaire validé, il faudra établir une condition afin de faire la requête en fonction du mode de recherche.
C'est-à-dire :

De plus, on peut ajouter d'autres options, comme par exemple sélectionner uniquement les entrées dont le champ champ1 contient les mots de la recherche et dont le champ champ2 a pour valeur 1.
Voici un exemple de requête permettant cela :
Code : SQL
1
SELECT * FROM matable WHERE champ1 LIKE '%motcle1%' AND champ1 LIKE '%motcle2%' AND champ2='1' ORDER BY id

Un exemple de code

Il est temps de passer de la théorie à la pratique. :D
Nous allons faire un code de recherche de sujets mettant en pratique tout ce que nous venons de voir.
Celui-ci offrira la possibilité de sélectionner uniquement les sujets fermés.

La base de données



Notre recherche se fait dans une table, il est donc indispensable que l'on en crée une. ;)
Nous allons l'appeler recherche et y insérer quelques entrées pour qu'elle ne soit pas vide. :)
Voici le code SQL pour créer la table et ses entrées :

Code : SQL
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
CREATE TABLE `recherche` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titre` text collate latin1_general_ci NOT NULL,
  `ferme` varchar(1) collate latin1_general_ci NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id` (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;
 
INSERT INTO `recherche` VALUES (1, 'Problème en PHP', '1');
INSERT INTO `recherche` VALUES (2, 'Tableaux en HTML', '0');
INSERT INTO `recherche` VALUES (3, 'Mon design', '1');
INSERT INTO `recherche` VALUES (4, 'Problème en Javascript', '0');
INSERT INTO `recherche` VALUES (5, 'PHP aidez moi', '0');

La recherche avec LIKE se fera dans le champ titre.
Quand le champ ferme vaut 0, cela signifie que le sujet est ouvert et quand il vaut 1, cela signifie qu'il est fermé.
N'hésitez surtout pas à rajouter d'autres entrées dans la table. ;)



Le formulaire



Il y a trois champs dans notre formulaire. Un de type texte dans lequel on entre les mots de la recherche, un autre en liste déroulante demandant le mode de recherche parmi les trois possibles, et un troisième en cases à cocher permettant de sélectionner uniquement les sujets fermés.
Voici le code du formulaire :

Code : HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<form method="post" action="recherche.php">
Votre recherche :
<input type="text" name="recherche" />
<br />
Votre mode de recherche :
<select name="mode">
<option value="expression_exacte">Expression exacte</option>
<option value="tous_les_mots">Tous les mots</option>
<option value="un_mot">Au moins un mot</option>
</select>
<br />
Sélectionner uniquement les sujets fermés :
<input name="sujets_fermes" type="checkbox" />
<br />
<input type="submit" value="Rechercher" name="rechercher" />
</form>



Le code PHP avec le formulaire



Nous allons maintenant utiliser les informations entrées par le visiteur dans le formulaire pour faire notre recherche. :)
On va nommer ce fichier recherche.php.

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
mysql_connect("", "", ""); //connexion à la bdd
mysql_select_db("");
if (isset($_POST['rechercher'])) //si on a validé le formulaire
{
$recherche = mysql_real_escape_string(htmlspecialchars($_POST['recherche'])); //sécurisation des variables
$mode = mysql_real_escape_string(htmlspecialchars($_POST['mode']));
if (isset($_POST['sujets_fermes'])) //si on a coché la case
{
$sujets_fermes = "AND ferme='1'";
}
else //si on ne l'a pas cochée
{
$sujets_fermes = '';
}
if ($mode == "tous_les_mots")
{
$and_ou_or = 'AND'; //on utilisera AND dans la boucle
}
else
{
$and_ou_or = 'OR'; //on utilisera OR dans la boucle
}
if ($mode == "expression_exacte") //si le mode de recherche est par expression exacte
{
$selection_recherche = mysql_query("SELECT * FROM recherche WHERE titre LIKE '%$recherche%' $sujets_fermes ORDER BY id DESC");
}
else //si le mode de recherche n'est pas par expression exacte
{
$mots = explode(" ", $recherche); //séparation des mots
$nombre_mots = count ($mots); //compte le nombre de mots
$valeur_requete = '';
for($nombre_mots_boucle = 0; $nombre_mots_boucle < $nombre_mots; $nombre_mots_boucle++) //tant que le nombre de mots de la recherche est supérieur à celui de la boucle, on continue en augmentant le nombre de mots de 1 à chaque fois
{
$valeur_requete .= '' . $and_ou_or . ' titre LIKE \'%' . $mots[$nombre_mots_boucle] . '%\''; //modification de la variable $valeur_requete
}
$valeur_requete = ltrim($valeur_requete,$and_ou_or); //suppression de AND ou de OR au début de la boucle
$selection_recherche = mysql_query("SELECT *
FROM recherche
WHERE $valeur_requete $sujets_fermes ORDER BY id DESC"); //requête avec le résultat de la boucle dedans
}
$nombre_resultats = mysql_num_rows($selection_recherche); //compte le nombre d'entrées sélectionnées par la recherche
if ($nombre_resultats == 0) //s'il n'y a pas de résultat
{
echo 'aucun resultat.<a href="recherche.php">recommencer</a>';
}
else //il y a au moins un résultat
{
echo 'nombre de résultats: ' . $nombre_resultats . ':<br /><br />'; //nombre de résultats
while($resultats = mysql_fetch_array($selection_recherche) ) //boucle affichant les résultats
{
echo '<strong>Numero:</strong> ' . $resultats['id'] . '<br />
<strong>Titre:</strong> ' . $resultats['titre'] . '<br />
<strong>Fermé:</strong> ' . $resultats['ferme'] . '<br /><br />';
}
echo '<a href="recherche.php">recommencer</a>';
}
}
else //si on n'a pas validé le formulaire, on l'affiche
{
?>
<form method="post" action="recherche.php">
Votre recherche :
<input type="text" name="recherche" />
<br />
Votre mode de recherche :
<select name="mode">
<option value="expression_exacte">Expression exacte</option>
<option value="tous_les_mots">Tous les mots</option>
<option value="un_mot">Au moins un mot</option>
</select>
<br />
Sélectionner uniquement les sujets fermés :
<input name="sujets_fermes" type="checkbox" />
<br />
<input type="submit" value="Rechercher" name="rechercher" />
</form>
<?php
}
mysql_close(); //déconnexion de la bdd
?>

Utilisez les mêmes fonctions de sécurité sur la recherche que celles que vous utilisez avant d'insérer vos entrées dans votre table.
Ici, j'ai utilisé mysql_real_escape_string et htmlspecialchars, mais peut-être que vous avez l'habitude d'utiliser htmlentities et ENT_QUOTES.
Si vous ne le faites pas, il risque d'y avoir des problèmes avec les recherches qui contiennent des caractères spéciaux. ;)


Et voilà, ce code est terminé. :D
Entrez des mots, choisissez le mode de recherche et cochez ou non la case afin de tester ce code.
Vous verrez que suivant le mode de recherche choisi ou suivant que la case est cochée ou non, le résultat pourra être différent même si les mots de la recherche sont les mêmes. :)

Q.C.M.

Quelle fonction permet de séparer les mots de la recherche ?
Quelle fonction permet de compter le nombre de mots après les avoir séparés grâce à la fonction de la première question ?
Code : SQL
1
SELECT * FROM matable WHERE monchamp LIKE '%motcle1%' AND LIKE '%motcle2%' AND champ2='1' ORDER BY id

Cette requête fonctionnera-t-elle ?


Ça y est, ce tutoriel est fini. :-°
Vous pouvez bien évidemment rajouter toutes sortes d'options, tout dépend des champs de votre table. :)
Et maintenant faire un moteur de recherche assez performant. :D
Auteur : dark-link
Noter et commenter ce tutoriel
Imprimer ce tutoriel

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 112 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.2517s (0.2404s)