8792 sujets

Développement web côté serveur, CMS

Bonjour,

Je viens de monter un moteur de recherche mais j'ai un petit soucis de codage.

Je propose de pouvoir saisir un ou plusieurs mots pour la recherche.
Par exemple : je veux chercher => carte postale
Si je tape - carte postale - ça sera le mot carte et le mot postale qui seront recherchés sur le site, mais si je tape - "carte postale" - (en guillements) ça sera la chaine "carte postale" qui sera recherchée dans le site.

Mon code fonction pour le premier cas (mot à mot) mais pas dans le deuxième (recheche de la chaine complète). Pourtant j'ai testé le contenu des mes variables et dans ce 2ème cas $mots compote bien la chaine entière.

Des idées ??

Mon formulaire (page index.php)
<form action="moteur.php" method="post" id="searchform">
  <input name="mot" type="text" class="input" size="30" />
  <input name="btn_chercher" type="submit" value="" id="btnGo" />
</form>


Mon code (page moteur.php)

<?PHP
$mot = strtolower($_POST['mot']);

// id = 0 = expression transmise contient un seul mot
// id = 1 = expression transmise contient plusieurs mots
$id = 0;

if (!eregi('"',$mot)) { //s'il n'y a pas de " dans l'expression transmise
	$mots = split(" ", $mot); //decoupe l'expression en fonction des espaces
	$id = 1;
} else {//s'il y a des " dans l'expression transmise
	//remplace les " par des espaces
	$mots = ereg_replace("[\"]", " ", $mot);
	//supprimer les caracteres \ ajouter par PHP
	$mots = ereg_replace("[\]", " ", $mots);
}

if ($id == 1) {
	for ($i=0 ; $i<count($mots) ; $i++) {
		$mots[$i] = ereg_replace("[\"]", " ", $mots[$i]);
	}
}

//ouvrir le repertoire courant (racine)
$repertoire = opendir(".");

//lecture des differents fichiers dans le repertoire
while ($fichier = readdir($repertoire)) {
	//on test pour voir si $fichier est un repertoire ou un fichier
	$ok = is_file($fichier);
	if ($ok) { //si c'est un fichier
		$open = fopen($fichier, "r");
		$contenu = fread($open, filesize($fichier));

		//s'il y a plusieurs variables
		if ($id == 1) {
			for ($i=0 ; $i<count($mots) ; $i++) {//pour chaque mot de l'expression
				if (eregi($mots[$i], $contenu)) { //si le mot recherche est contenu dans le fichier, afficher le lien vers la page
					echo ($mots[$i].' a &eacute;t&eacute; trouv&eacute; dans le fichier <a href="affichage.php?fichier='.$fichier.'&mot='.$mots[$i].'">'.$fichier.'</a><br />');
				} else {
					echo ('Aucune correspondance au mot '.$mots[$i].' n\'a &eacute;t&eacute; trouv&eacute;e dans le fichier '.$fichier.'.<br />');
				}
			}
		}

		//s'il y a qu'une seule variable
		if ($id == 0) {
			if (eregi($mots, $contenu)) { //rechercher le mot dans le fichier et afficher les liens
				echo ($mots.' a &eacute;t&eacute; trouv&eacute; dans le fichier <a href="affichage.php?fichier='.$fichier.'&mot='.$mots.'">'.$fichier.'</a><br />');
			} else {
				echo ('Aucune correspondance avec '.$mots.' n\'a &eacute;t&eacute; trouv&eacute;e dans le fichier '.$fichier.'.<br />');
			}
		}

		//fermeture du fichier
		fclose($open);
	}
}
?>

Comme tu remplaces les " par des espaces, tu cherches " carte postale ". Donc si ton texte contient "Envoie-moi une carte postale.", ça ne marchera pas.

Il vaudrait mieux remplacer les " par rien.

De plus, tu peux avantageusement remplacer ereg_replace("[\]", " ", $mots) par stripslashes($mots), et ereg_replace par preg_replace qui est plus rapide selon la doc PHP.
Un petit truc pouvant aider :

// Entités entre guillemets restent exactes
$preg_query = str_replace("/","\/",$_POST['mot']);
$out = array();
if (preg_match_all("/\"([^\"]*)\"/i",$preg_query,$out))
{
	foreach ($out[1] as $word)
	{
		$mots[] = $word;
		$preg_query = str_replace("\"$word\"","",$preg_query);	// Suppression des mots clés déjà enregistrés
	}
}

// Entités restantes
$res = explode(" ",$preg_query);
if (!empty($res))
{
	array_merge($mots,$res);
}


Tu devrais trouver après ça dans ton tableau les mots de la chaîne de requête découpés correctement. Le preg_match_all te permet de récupérer toutes les expressions entre guillemet, je les supprime ensuite de la requete. Il ne reste donc après que les mots qui n'ont pas été mis entre guillemets.
A plus