8768 sujets

Développement web côté serveur, CMS

Bonjour,

J'ai mon moteur de recherche que je traîne de site en site... et qui fonctionne très bien. Sauf qu'il ne permet la recherche que d'un seul mot (ex: carte) ou d'un groupe de mot se suivant exactement (ex: carte postale).

Voici le formulaire de recherche :

<div id="moteurderecherche">
	<form action="moteurderechercheresult.php" method="post">
		<p>
			<input type="search" name="requete" id="requete" size="30" placeholder="Recherche" maxlength="25" accesskey="4" /> 
			<input class="bouton2" type="submit" name="submit" id="submit" value="Ok" />
		</p>
	</form>
</div>


et voici la page de résultat (dans cette version, j'utilise une jointure) :

<?php
if(isset($_POST['requete']) AND $_POST['requete'] != NULL) {
	$requete = htmlentities($_POST['requete'], ENT_QUOTES);

				
	include('connexion_sql.php');

	$query=$bdd->query("SELECT * 
				FROM premiere_table AS aa 
				RIGHT JOIN seconde_table AS ar
				ON aa.titre = ar.titre
				WHERE aa.article OR ar.article LIKE '%" .$requete. "%' 
				OR aa.signature OR ar.signature LIKE '%" .$requete. "%'
				") or die(print_r($bdd->errorInfo()));
	$nb_resultats  = $query->rowCount(); 
			
			
	if($nb_resultats > 0)  {
		echo 'Nous avons ' .$nb_resultats;
			if($nb_resultats > 1) { 
				echo ' résultats'; 
			} 
			else { 
				echo ' résultat'; 
			}
		echo ' pour votre requête : <strong>' .$requete. '</strong><br/><br />';
			while($donnees = $query->fetch()) {
				echo '<a href="http://www.lesite.fr/' .stripslashes($donnees['titre']). '">' .stripslashes($donnees['titre']). '</a><br />';
			} 
		}
		else if($nb_resultats == 0) { 
			echo 'Nous n\'avons trouvé aucun résultat pour votre requête : <span class="gras">' .$requete. '</span>';
		}
	$query->closeCursor(); 
} 
 ?>	


Je souhaite augmenter ce code de façon à pouvoir effectuer une recherche avec au moins deux mots distincts (ex : carte Strasbourg).

Veut-on bien me guider siouplè ? Smiley smile

Merci
Modifié par Marie08 (19 Jun 2015 - 13:21)
Bonsoir,
J'ai bossé il y a quelques années sur un moteur de recherche pour un site de photos "libres de droits", l'idée étant de permettre à l'internaute de saisir des mots pour trouver les images comportant les mots-clefs saisis.

Donc il y a deux étapes :

1 - Traitement de la requête saisie

stocker dans un tableau PHP les mots saisis après suppression des double espaces, des points, des virgules des tirets et autres caractères parasites dans la chaîne saisie ; une fois nettoyée, la fonction explode nous donnera un tableau des mots à chercher

2 - Requête MySQL : on va construire la requête qui sera de la forme :
(suite)

il faut ajouter le caractère '%' avant et après chaque mot,
donc en parcourant le tableau pour ajouter les caractères % à chaque mot du tableau

et ensuite parcourir le tableau pour ajouter les lignes de la requête
avec une boucle foreach qui aura pour résultat ;

WHERE champ LIKE '$mot_1'
AND champ LIKE '$mot_2'
...
AND champ LIKE '$mot_n'

Reste le problème des fautes d''orthographe et des erreurs de saisie...
Libellule ? libelulle ? Libelule ? Libélulle ? coccinele ? cocinnelle ? coccinnele ?

la fonction "levenshtein" de PHP permet de trouver les mots qui diffèrent par n lettres d'un mot donné, bien pratique !

Mais attention : on a aussi la question des singuliers/pluriels ...
Si j'entre "industries chimiques" je dois trouver tous les articles contenant "industrie chimique"

Mais ceci est une autre histoire, comme disait Kipling
Bonjour et merci beaucoup Farang Smiley biggrin

Je vais travailler là-dessus et reviendrai poster.

A plus tard,
Bonjour,

C'est idiot mais je rame bêtement sur quelque chose qui ne me semble pas pourtant compliqué...et c'est pénible.

J'ai réalisé la première étape mais je ne parviens pas à formuler la seconde...


<?php
if(isset($_POST['requete']) AND $_POST['requete'] != NULL) {
	$requete = htmlentities($_POST['requete'], ENT_QUOTES);
				
	$search  = array('  ', '-', '_', ',', ';');
	$replace = array(' ');
	$requete=str_replace($search, $replace, $requete);
				
	$array=explode(" ",$requete);
	//$requete = explode(" ", $requete);
	//var_dump($requete);

	echo '<pre>'; //juste pour visualiser le tableau
		print_r($array);
	echo '</pre>';
				
				
	foreach($array as $requete){
		echo $requete. '<br />'; //juste pour visualiser le résultat
	}
				
	// la suite n'a pas été encore modifiée (enfin si, j'ai retiré ma jointure de table)			
				
	include('connexion_sql.php');
				
	$query=$bdd->query("SELECT * 
		FROM matable
		WHERE titre LIKE '%" .$requete. "%' 
		OR article LIKE '%" .$requete. "%' 
		OR signature LIKE '%" .$requete. "%' 
		ORDER BY datepublication DESC
	") or die(print_r($bdd->errorInfo()));
	
	$nb_resultats  = $query->rowCount(); 
			
	if($nb_resultats > 0)  {
		echo 'Nous avons ' .$nb_resultats;
			if($nb_resultats > 1) { 
				echo ' résultats'; 
			} 
			else { 
				echo ' résultat'; 
			}
		echo ' pour votre requête : <strong>' .$requete. '</strong><br/><br />';

		while($donnees = $query->fetch()) {
			echo '<article>
				<header>
					<h1>' .stripslashes($donnees['titre']). '</h1>
						</header>';
								
					$resume = bbcode(str_replace('<br/>', "\n",$donnees["resume"]));
						echo '<p>' .stripslashes($donnees['resume']). '<br />
								
					<footer><a href="article.php?titre=' .stripslashes($donnees["titre"]). '" title="Lire le détail de l\'article">Lire la suite...</a></p></footer>
			</article>';
		} 
	}
	else if($nb_resultats == 0) { 
		echo 'Nous n\'avons trouvé aucun résultat pour votre requête : <span class="gras">' .$requete. '</span>';
	}
	$query->closeCursor(); 
} 
 ?>	


Je vais donc avoir besoin que l'on m'explique encore certains points... Merci Smiley smile
Changement de cap !

Un forumien sur developpez.net m'a écrit :
" Je t'invite à aller faire un tour du côté des recherches FULL TEXT "

Après étude de cette fonction ici, puis ici et enfin , j'ai réussi à obtenir ce que je voulais. Je poste mon code dans le cas où il pourrait être utile à d'autres.

Voici le formulaire de recherche :

<div id="moteurderecherche">
<form action="moteurderechercheresult.php" method="post">
<p>
<input type="search" name="requete" id="requete" size="30" placeholder="Recherche" maxlength="25" accesskey="4" />
<input class="bouton2" type="submit" name="submit" id="submit" value="Ok" />
</p>
</form>
</div> 


Et la page de résultat :

<?php
if(isset($_POST['requete']) AND $_POST['requete'] != NULL) {
$requete = htmlentities($_POST['requete'], ENT_QUOTES);

$search = array(' ', '_', ',', ';');
$replace = array(' ');
$requete=str_replace($search, $replace, $requete);



include('connexion_sql.php');

$query=$bdd->query("SELECT *
FROM ma_table
WHERE MATCH(titre, soustitre, article, signature) AGAINST ('$requete' in boolean mode)
") or die(print_r($bdd->errorInfo()));

$nb_resultats = $query->rowCount();

if($nb_resultats > 0) {
echo 'Nous avons ' .$nb_resultats;
if($nb_resultats > 1) {
echo ' résultats';
}
else {
echo ' résultat';
}
echo ' pour votre requête : <strong>' .$requete. '</strong><br/><br />';

while($donnees = $query->fetch()) {
echo '<article>
<header>
<h1>' .stripslashes($donnees['titre']). '</h1>
</header>';

$resume = bbcode(str_replace('<br/>', "\n",$donnees["resume"]));
echo '<p>' .stripslashes($donnees['resume']). '<br />

<footer><a href="article.php?titre=' .stripslashes($donnees["titre"]). '" title="Lire le détail de l\'article">Lire la suite...</a></p></footer>
</article>';
}
}
else if($nb_resultats == 0) {
echo 'Nous n\'avons trouvé aucun résultat pour votre requête : <span class="gras">' .$requete. '</span>';
}
$query->closeCursor();
}
?> 


Comment créer un index FULL TEXT ?
Rien de plus facile, un simple ALTER TABLE permet d'ajouter un index fulltext sur une ou plusieurs colonnes.Voici un exemple :
	
ALTER TABLE `ma_table` ADD FULLTEXT INDEX `search` (`champ1`, `champ2`, `champ3`);

Lire la suite...


Voilà, à toutes fins utiles !

Merci à toi aussi Farang !


Edit (21h20) : le truc qui m'ennuie c'est qu'il recherche les mots exacts. Si l'internaute recherche "bienvenu" au lieu de "bienvenue" il n'aura pas de résultat. Avec mon code y a t-il une astuce comme avec LIKE et les % ?
Modifié par Marie08 (20 Jun 2015 - 05:48)
" Edit (21h20) : le truc qui m'ennuie c'est qu'il recherche les mots exacts. Si l'internaute recherche "bienvenu" au lieu de "bienvenue" il n'aura pas de résultat. Avec mon code y a t-il une astuce comme avec LIKE et les % ? "

Je me réponds...
Je suis passée à côté de la subtilité proposée dans un autre topic, il suffit de mettre * : bienvenu* affichera donc également le résultat avec bienvenue ou bienvenues.

Voilà, je passe le sujet en [Résolu]

Edit : voici ce lien intéressant également sur la recherche par FULL TEXT
Modifié par Marie08 (19 Jun 2015 - 14:37)