Moteur de recherche et accents

Petit nouveau ! | 1 Messages

29 janv. 2011, 12:47

Bonjour,

J'ai un petit souci php, j'ai une base de données Mysql avec des produits dont l'une des colonne contient le nom du produit, sur laquelle mon moteur de recherche interne effectue les recherches.

Or dans la base les nom des produits sont enregistrés de cette facon :

Planche pour déjeuner

Ce qui fait que si un client vient à rechercher : déjeuner, il ne trouve rien

J'ai donc mis un htmlentities() pour palier à ce pb ce qui donne :

<?php
$keywords = $_POST['keywords'];
$keywords = htmlentities($keywords);

// Puis la requête SQL

.... where products_name like '%" . $keywords . "%'
?>

Sauf que si un client recherche dejeuner, il ne trouve aucun résultat, comment puis-je contourner ce problème ?

Cdt,

ViPHP
AB
ViPHP | 5818 Messages

29 janv. 2011, 19:12

C'est pas vraiment un problème de php, mais plutôt le fait que tu aies enregistré les données en bdd avec htmlentities.

Le mieux serait que tu puisse enregistrer les données en bdd telles qu'elles devraient l'être, c'est à dire sans htmlentities.
Et tu pourrais convertir tes tables existantes avec html_entity_decode().
Cela dit il faudra ensuite que tu vérifie l'affichage de tes variables dans le html pour leur appliquer la fonction htmlentities (ou plus simplement htmlspecialchars).

Autrement je vois pas de solution, à part des méthodes qui seront un gouffre à performance pour ton moteur de recherche... :-k

Eléphant du PHP | 245 Messages

31 janv. 2011, 11:39

Je ce que je propose change un peu la stucture du moteur :

Tu ajoute une colonne mots_cles à ta table SQL.
Tu y rentre des mots clés à un format adapté alphanumérique minuscule par exemple grâce à une fonction PHP de formatage que tu crées.
function supprime_accents($chaine){

	$cible = array(
            'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'A', 'A',
            'Ç', 'C', 'C', 'Œ',
            'D', 'Ð',
            'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'a', 'a',
            'ç', 'c', 'c', 'œ',
            'd', 'd',
            'È', 'É', 'Ê', 'Ë', 'E', 'E',
            'G',
            'Ì', 'Í', 'Î', 'Ï', 'I',
            'L', 'L', 'L',
            'è', 'é', 'ê', 'ë', 'e', 'e',
            'g',
            'ì', 'í', 'î', 'ï', 'i',
            'l', 'l', 'l',
            'Ñ', 'N', 'N',
            'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'O',
            'R', 'R',
            'S', 'S', 'Š',
            'ñ', 'n', 'n',
            'ò', 'ó', 'ô', 'ö', 'ø', 'o',
            'r', 'r',
            's', 's', 'š',
            'T', 'T',
            'Ù', 'Ú', 'Û', 'U', 'Ü', 'U', 'U',
            'Ý', 'ß',
            'Z', 'Z', 'Ž',
            't', 't',
            'ù', 'ú', 'û', 'u', 'ü', 'u', 'u',
            'ý', 'ÿ',
            'z', 'z', 'ž',

            );

	$rempl = array(
            'A', 'A', 'A', 'A', 'A', 'A', 'AE', 'A', 'A',
            'C', 'C', 'C', 'CE',
            'D', 'D',
            'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'a', 'a',
            'c', 'c', 'c', 'ce',
            'd', 'd',
            'E', 'E', 'E', 'E', 'E', 'E',
            'G',
            'I', 'I', 'I', 'I', 'I',
            'L', 'L', 'L',
            'e', 'e', 'e', 'e', 'e', 'e',
            'g',
            'i', 'i', 'i', 'i', 'i',
            'l', 'l', 'l',
            'N', 'N', 'N',
            'O', 'O', 'O', 'O', 'O', 'O', 'O',
            'R', 'R',
            'S', 'S', 'S',
            'n', 'n', 'n',
            'o', 'o', 'o', 'o', 'o', 'o',
            'r', 'r',
            's', 's', 's',
            'T', 'T',
            'U', 'U', 'U', 'U', 'U', 'U', 'U',
            'Y', 'Y',
            'Z', 'Z', 'Z',
            't', 't',
            'u', 'u', 'u', 'u', 'u', 'u', 'u',
            'y', 'y',
            'z', 'z', 'z',

            );
	$fich = str_replace($cible, $rempl, $chaine);


	return $fich;

}
function conversion_mots_cles($string,$separateur=' '){
	$sortie=$chaine;
	$sortie=strtolower($sortie);
	$sortie=supprime_accents($sortie);
	$expression='/[^0-9a-zA-Z]/';
	$sortie = preg_replace($expression,$separateur,$sortie);
	$sortie=trim($sortie,$separateur);
	
	return $sortie;

}


tu insères les mots clés dans ta table après les avoir traités avec la fonction du dessus.
$keywords = conversion_mots_cles($_POST['titre']);
$requeteSQL = "update latable set ... , mots_cles = '$keywords' where id = $id" ;
Lorsqu'un utilisateur tape un mots clé dans le moteur, tu formate celui ci avec la même fonction.
$keywords = $_POST['keywords'];
$keywords = conversion_mots_cles($keywords);

// Puis la requête SQL

.... where products_name like '%" . $keywords . "%'


Ainsi tu es sur d'avoir les mêmes stuctures de mots clés pour ta recherche.

Pour la fonction conversion_mots_cles($keywords), tu l'adapte à ta guise, tu peux aussi l'aménager pour traiter les pluriels, les articles et pronoms, etc.

ViPHP
AB
ViPHP | 5818 Messages

31 janv. 2011, 20:58

Tout ça pour avoir enregistré des données en bdd avec htmlentities, ça fait beaucoup.

Autant un champ de mots clés peut se justifier pour optimiser des recherches, autant quand il s'agit de doubler une colonne de noms de produits cela fait redondant.

S'il n'est pas trop tard dans l'avancement du projet je pense que changer l'enregistrement en bdd serait le plus optimisé. D'une part on gagne pas mal de place dans les tables sans ces entités qui n'ont rien à faire dans la base, d'autre part en cas d'export de la base les données seront propres. Et ensuite une simple collation general_ci permettra de faire une recherche insensible aux accents et à la casse.

Cela dit ta solution est une alternative qui peut même apporter un plus en terme de recherche à condition que chaque produit soit décrit avec plus de mots clés que son simple nom...