[PHP] moteur de recherche interne, requête insensible aux accents
13 messages
• Page 1 sur 1
Consultez la formation à Google Analytics de WebRankInfo / Ranking Metrics
- leica69
- Nouveau WRInaute

- Messages: 30
- Inscription: 25 Oct 2004
[PHP] moteur de recherche interne, requête insensible aux accents
Bonjour,
je suis en train de faire un moteur de recherche interne pour mon site.
1/ Je récupère le mot cle de recherche transmis par formulaire:
2/ je fais une recherche dans ma base de données (PHP5, utf8_unicode_ci)
Je souhaite que les mots recherché soient surlignés dans l'affichage final
Maintenant, je vous explique mon souci:
Quand je fais la recherche SQL, elle est insensible aux accents.
Quand je fais la recherche PHP, elle est insensible à la casse mais sensible aux accents.
Si je fais une recherche sur "pre":
- SQL va me retourner les enregistrements contenant "précision", "âpre", "premier",...
- PHP va uniquement surligner "âpre", "premier"
Mon problème est une incohérence des recherches. Je vais avoir des champs de texte sans rien de surligné, c'est déroutant pour l'utilisateur (et pour moi).
Je souhaite avoir deux recherches cohérentes:
Soit tout insensible aux accents // Soit tout sensible aux accents
J'ai essayé de remplacer tous les caractères accentués par leur équivalent sans accent. Le pb est que je me retrouve avec un texte de résultat sans les accents. Je veux un texte juste (accentué) en retour.
J'espère que qqn pourra m'aider!!
D'avance, merci,
Antonio
je suis en train de faire un moteur de recherche interne pour mon site.
1/ Je récupère le mot cle de recherche transmis par formulaire:
- Code: Tout sélectionner
$recherche = $_POST['rech'];
$recherche = trim($recherche);
2/ je fais une recherche dans ma base de données (PHP5, utf8_unicode_ci)
Je souhaite que les mots recherché soient surlignés dans l'affichage final
- Code: Tout sélectionner
$requete="SELECT * FROM table WHERE champ1 LIKE '%$recherche%' OR champ2 LIKE '%$recherche%''";
$resultat=mysql_query($requete) or die ("Problème lors de la requête. Erreur: ".mysql_error());
while($ligne=mysql_fetch_array($resultat)){
$valeur1 = $ligne[champ1];
$valeur2 = $ligne[champ2];
// recherche et remplacement du mot de la recherche pour l'entourer d'un <span> de mise ne forme
$pattern = '('. quotemeta($recherche) .')';
$replacement = "<span class='selection'>\\1</span>";
$valeur1 = eregi_replace($pattern, $replacement, $valeur1);
$valeur2 = eregi_replace($pattern, $replacement, $valeur2);
// Affichage du résultat mis en forme
echo "<p>$valeur1 </p>";
echo "<p>$valeur2 </p>";
}
Maintenant, je vous explique mon souci:
Quand je fais la recherche SQL, elle est insensible aux accents.
Quand je fais la recherche PHP, elle est insensible à la casse mais sensible aux accents.
Si je fais une recherche sur "pre":
- SQL va me retourner les enregistrements contenant "précision", "âpre", "premier",...
- PHP va uniquement surligner "âpre", "premier"
Mon problème est une incohérence des recherches. Je vais avoir des champs de texte sans rien de surligné, c'est déroutant pour l'utilisateur (et pour moi).
Je souhaite avoir deux recherches cohérentes:
Soit tout insensible aux accents // Soit tout sensible aux accents
J'ai essayé de remplacer tous les caractères accentués par leur équivalent sans accent. Le pb est que je me retrouve avec un texte de résultat sans les accents. Je veux un texte juste (accentué) en retour.
J'espère que qqn pourra m'aider!!
D'avance, merci,
Antonio
-

forty - WRInaute passionné

- Messages: 1701
- Inscription: 30 Oct 2008
Re: [PHP] moteur de recherche interne, requête insensible aux accents
tu peux utiliser un code comme celui ci pour transformer ta mot recherché en regex. ca transforme par exemple "Eléphant" en "[eèéêë]l[eèéêë]phant" pour alimenter ton partern
- Code: Tout sélectionner
function regexAccents($chaine) {
$accent = array('a','à','á','â','ã','ä','å','c','ç','e','è','é','ê','ë','i','ì','í','î','ï','o','ð','ò','ó','ô','õ','ö','u','ù','ú','û','ü','y','ý','ý','ÿ');
$inter = array('%01','%02','%03','%04','%05','%06','%07','%08','%09','%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');
$regex = array('[aàáâãäå]','[aàáâãäå]','[aàáâãäå]','[aàáâãäå]','[aàáâãäå]','[aàáâãäå]','[aàáâãäå]',
'[cç]','[cç]',
'[eèéêë]','[eèéêë]','[eèéêë]','[eèéêë]','[eèéêë]',
'[iìíîï]','[iìíîï]','[iìíîï]','[iìíîï]','[iìíîï]',
'[oðòóôõö]','[oðòóôõö]','[oðòóôõö]','[oðòóôõö]','[oðòóôõö]','[oðòóôõö]','[oðòóôõö]',
'[uùúûü]','[uùúûü]','[uùúûü]','[uùúûü]',
'[yýýÿ]','[yýýÿ]','[yýýÿ]','[yýýÿ]');
$chaine = str_ireplace($accent, $inter, $chaine);
$chaine = str_replace($inter, $regex, $chaine);
return $chaine;
}
- leica69
- Nouveau WRInaute

- Messages: 30
- Inscription: 25 Oct 2004
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Merci pour l'astuce. Théoriquement ça devrait fonctionner. Mais malheureusement ce n'est pas le cas pour moi.
J'ai fait une requête simplifiée utilisant ton idée, histoire d'identifier le problème.
ma chaîne de départ
la chaîne à mettre en gras:
La substitution pour mettre en gras
le remplacement
et j'obtiens
dans le code source: poire <b>tr�</b>�s s<b>tre</b>ss <b>tre</b>sse <b>tr�</b>�ssaillir(SIC)
à l'affichage: poire tr��s stress tresse tr��ssaillir(SIC)
(ce qui est étonnant c'est que le caractère soit doublé. Le gras fonctionne mais n'est pas affiché dans ce dernier exemple)
les caractères d'erreur sont des losanges avec des ? à l'intérieur.
Je suis en UTF-8 dans tout le processus et mon navigateur (firefox) est correctement réglé.
Uni idée de solution??
J'ai fait une requête simplifiée utilisant ton idée, histoire d'identifier le problème.
ma chaîne de départ
- Code: Tout sélectionner
$desc = "poire très stress tresse tréssaillir(SIC)";
la chaîne à mettre en gras:
- Code: Tout sélectionner
$pattern = "(tr[eèé])"; // qui devrait correspondre à tre, trè, tré
La substitution pour mettre en gras
- Code: Tout sélectionner
$replacement = "<b>\\1</b>";
le remplacement
- Code: Tout sélectionner
$test3 = eregi_replace($pattern, $replacement, $desc);
echo "$test3";
et j'obtiens
dans le code source: poire <b>tr�</b>�s s<b>tre</b>ss <b>tre</b>sse <b>tr�</b>�ssaillir(SIC)
à l'affichage: poire tr��s stress tresse tr��ssaillir(SIC)
(ce qui est étonnant c'est que le caractère soit doublé. Le gras fonctionne mais n'est pas affiché dans ce dernier exemple)
les caractères d'erreur sont des losanges avec des ? à l'intérieur.
Je suis en UTF-8 dans tout le processus et mon navigateur (firefox) est correctement réglé.
Uni idée de solution??
-

forty - WRInaute passionné

- Messages: 1701
- Inscription: 30 Oct 2008
Re: [PHP] moteur de recherche interne, requête insensible aux accents
c'est sûrement a cause de l'utf-8. comme les lettres accentuées sont sur deux caractères les [] matchent toutes les lettres.
essaye de remplacer [eèé] par (e|è|é)
essaye de remplacer [eèé] par (e|è|é)
- leica69
- Nouveau WRInaute

- Messages: 30
- Inscription: 25 Oct 2004
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Ca ne fonctionne toujours pas.
Je joue un peu avec l'encodage/décodage UTF-8 / ISO-8859-1 pour essayer de contourner le problème mais je bloque encore.
j'obtiens ça dans le code source de la page
Ce qui me surprend c'est que seul le premier "caractère" (&) du caractère accentué soit dans la balise <b>
Je joue un peu avec l'encodage/décodage UTF-8 / ISO-8859-1 pour essayer de contourner le problème mais je bloque encore.
- Code: Tout sélectionner
$desc = "poire très stress tresse tréssaillir(SIC)";
$desc = htmlentities($desc,ENT_NOQUOTES, "UTF-8");
//desc: poire très stress tresse tréssaillir(SIC)
$pattern = "(tr[è|e|é])";
$pattern = htmlentities($pattern,ENT_NOQUOTES, "UTF-8");
//pattern: (tr[è|e|é])
$replacement = "<b>\\1</b>";
$test3 = eregi_replace($pattern, $replacement, $desc);
j'obtiens ça dans le code source de la page
- Code: Tout sélectionner
poire <b>tr&</b>egrave;s s<b>tre</b>ss <b>tre</b>sse <b>tr&</b>eacute;ssaillir(SIC)
Ce qui me surprend c'est que seul le premier "caractère" (&) du caractère accentué soit dans la balise <b>
-

forty - WRInaute passionné

- Messages: 1701
- Inscription: 30 Oct 2008
Re: [PHP] moteur de recherche interne, requête insensible aux accents
tu ne peux pas mettre [è|e|é] car les crochets autorisent les caractères & e g r a v c u t et |
pour indiquer des chaînes il faut mettre entre parenthèse comme indiqué dans le précédent message : (è|e|é)
pour indiquer des chaînes il faut mettre entre parenthèse comme indiqué dans le précédent message : (è|e|é)
- leica69
- Nouveau WRInaute

- Messages: 30
- Inscription: 25 Oct 2004
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Je n'avais pas vu les parenthèses!!!!!
Ca fonctionne! J'ai quand même du jongler avec les UTF-8 et ISO
Voici le code, si ça peut aider qqn un jour:
Ca fonctionne! J'ai quand même du jongler avec les UTF-8 et ISO
Voici le code, si ça peut aider qqn un jour:
- Code: Tout sélectionner
function regexAccents($chaine) {
$accent = array('a','à','á','â','ã','ä','å','c','ç','e','è','é','ê','ë','i','ì','í','î','ï','o','ð','ò','ó','ô','õ','ö','u','ù','ú','û','ü','y','ý','ý','ÿ');
$inter = array('%01','%02','%03','%04','%05','%06','%07','%08','%09','%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');
$regex = array('(a|à|á|â|ã|ä|å)','(a|à|á|â|ã|ä|å)','(a|à|á|â|ã|ä|å)','(a|à|á|â|ã|ä|å)','(a|à|á|â|ã|ä|å)','(a|à|á|â|ã|ä|å)','(a|à|á|â|ã|ä|å)',
'(c|ç)','(c|ç)',
'(è|e|é|ê|ë)','(è|e|é|ê|ë)','(è|e|é|ê|ë)','(è|e|é|ê|ë)','(è|e|é|ê|ë)',
'(i|ì|í|î|ï)','(i|ì|í|î|ï)','(i|ì|í|î|ï)','(i|ì|í|î|ï)','(i|ì|í|î|ï)', '(o|ð|ò|ó|ô|õ|ö)','(o|ð|ò|ó|ô|õ|ö)','(o|ð|ò|ó|ô|õ|ö)','(o|ð|ò|ó|ô|õ|ö)','(o|ð|ò|ó|ô|õ|ö)','(o|ð|ò|ó|ô|õ|ö)','(o|ð|ò|ó|ô|õ|ö)', '(u|ù|ú|û|ü)','(u|ù|ú|û|ü)','(u|ù|ú|û|ü)','(u|ù|ú|û|ü)',
'(y|ý|ý|ÿ)','(y|ý|ý|ÿ)','(y|ý|ý|ÿ)','(y|ý|ý|ÿ)');
$chaine = str_ireplace($accent, $inter, $chaine);
$chaine = str_replace($inter, $regex, $chaine);
return $chaine;
}
$recherche = $_POST['rech'];
$recherche = trim($recherche);
$pattern = '('. $recherche .')';
$pattern = regexAccents($pattern);
$pattern = htmlentities($pattern,ENT_NOQUOTES, "ISO-8859-1");
$replacement = "<span class='selection'>\\1</span>";
if($_POST['rech'] != ""){
if (strlen($_POST['rech']) >= 3){
echo "<p>Résultat de la recherche pour <strong>$recherche</strong></p>";
$requete="SELECT * FROM table WHERE champ1 LIKE '%$recherche%' OR champ2 LIKE '%$recherche%' ";
$resultat=mysql_query($requete) or die ("Problème lors de la requête. Erreur: ".mysql_error());
if (mysql_num_rows($resultat) > 0){
echo "\n<h2>Huiles essentielles</h2>\n";
}
while($ligne=mysql_fetch_array($resultat)){
$val1 = $ligne[champ1];
$val2 = $ligne[champ2];
$val1 = html_entity_decode(eregi_replace($pattern, $replacement, htmlentities($val1,ENT_NOQUOTES, "ISO-8859-1")));
$val2 = html_entity_decode(eregi_replace($pattern, $replacement, htmlentities($val2,ENT_NOQUOTES, "ISO-8859-1")));
if(preg_match("/".$pattern."/i",$val1 ) > 0 OR preg_match("/".$recherche."/i",$val1 ) > 0){
echo "\n$val1 ";
}
if(preg_match("/".$pattern."/i",$val2 ) > 0 OR preg_match("/".$recherche."/i",$val2 ) > 0){
echo "\n$val2 ";
}
} else {
echo "\n<p>Votre recherche doit comporter au moins trois caractères</p>\n";
}
} else {
echo "\n<p>Veuillez saisir un mot pour effectuer votre recherche.</p>\n";
}
}
-

blman - WRInaute accro

- Messages: 3077
- Inscription: 5 Sep 2003
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Réponse hors sujet, mais tu gagnerais en performance en faisant ta requête SQL ainsi :
Les OR sont vraiment gourmand en ressources. En concaténant tes champs, tu gagne en performance.
- Code: Tout sélectionner
$requete="SELECT * FROM table WHERE CONCAT(champ1," ",champ2) LIKE '%$recherche%'";
Les OR sont vraiment gourmand en ressources. En concaténant tes champs, tu gagne en performance.
- leica69
- Nouveau WRInaute

- Messages: 30
- Inscription: 25 Oct 2004
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Je me rends compte d'un souci supplémentaire.
Une partie du texte de ma base contient du formatage HTML <strong>Nom</strong>, par exemple.
Comment faire pour que ma recherche ne prenne pas en compte mes balises?
Pour rappel, j'ai ceci:
Je dois modifier mon critère de recherche la bonne syntaxe. Pour l'instant, j'en suis là:
Dans ce cas précis, si je recherche "tron", c'est la catastrophe!!!
Une partie du texte de ma base contient du formatage HTML <strong>Nom</strong>, par exemple.
Comment faire pour que ma recherche ne prenne pas en compte mes balises?
Pour rappel, j'ai ceci:
- Code: Tout sélectionner
$search = '('. $search .')';
$search = regexAccents($search); // voir posts précédents, c'est pour être insensible aux accents
$search = htmlentities($search,ENT_NOQUOTES, "ISO-8859-1");
$valeur = html_entity_decode(eregi_replace($search, $replacement, htmlentities($valeur,ENT_NOQUOTES, "ISO-8859-1")));
Je dois modifier mon critère de recherche la bonne syntaxe. Pour l'instant, j'en suis là:
- Code: Tout sélectionner
$search = '([^<][\S]*)('. $search .')([\S]*[^>])';
Dans ce cas précis, si je recherche "tron", c'est la catastrophe!!!
-

forty - WRInaute passionné

- Messages: 1701
- Inscription: 30 Oct 2008
Re: [PHP] moteur de recherche interne, requête insensible aux accents
il y a peut-être une piste avec la fonction preg_replace_callback pour extraire tout ce qui n'est pas balise et faire ensuite ton replace mais je ne suis pas spécialiste
-

blman - WRInaute accro

- Messages: 3077
- Inscription: 5 Sep 2003
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Leica69,
personnellement, j'ajouterais un champs à ma table qui contient une chaine avec tous tes champs déjà concaténés et formaté (sans balise HTML, sans accent, tout en minuscule et sans les mots qui peuvent être des stop words). Tu indexera ton contenu dans ce champ à chaque fois que tu met à jour la ligne concernée dans ta table.
Tu y gagnera énormément en ressource et en simplicité au niveau de la recherche. Tu pourrais par exemple l'indexer en FULLTEXT pour gagner en pertinence ou plus facilement le charger en mémoire si tu veux faire de la correction orthographique.
Parce que là, en voyant la manière dont tu fais la recherche et comment tu la traite en sortie, à mon avis, tu es mal parti. Essaye de traiter tes données au maximum en entrée (indexation de tes keywords)
PS : sinon tu a la fonction strip_tags() en PHP pour retirer les balises HTML : http://fr2.php.net/strip-tags
personnellement, j'ajouterais un champs à ma table qui contient une chaine avec tous tes champs déjà concaténés et formaté (sans balise HTML, sans accent, tout en minuscule et sans les mots qui peuvent être des stop words). Tu indexera ton contenu dans ce champ à chaque fois que tu met à jour la ligne concernée dans ta table.
Tu y gagnera énormément en ressource et en simplicité au niveau de la recherche. Tu pourrais par exemple l'indexer en FULLTEXT pour gagner en pertinence ou plus facilement le charger en mémoire si tu veux faire de la correction orthographique.
Parce que là, en voyant la manière dont tu fais la recherche et comment tu la traite en sortie, à mon avis, tu es mal parti. Essaye de traiter tes données au maximum en entrée (indexation de tes keywords)
PS : sinon tu a la fonction strip_tags() en PHP pour retirer les balises HTML : http://fr2.php.net/strip-tags
- leica69
- Nouveau WRInaute

- Messages: 30
- Inscription: 25 Oct 2004
Re: [PHP] moteur de recherche interne, requête insensible aux accents
Salut,
Je m'en suis sorti avec strip_tags()
C'est vrai que pour la suite, si je complexifie le traitement de la base, je devrais passer par une colonne qui regroupera mes entrées.
En tout cas, merci pour ta solution.
Je m'en suis sorti avec strip_tags()
C'est vrai que pour la suite, si je complexifie le traitement de la base, je devrais passer par une colonne qui regroupera mes entrées.
En tout cas, merci pour ta solution.
13 messages
• Page 1 sur 1
Formation recommandée sur ce thème :
Formation Google Analytics : en 2 jours, apprenez comment exploiter l'essentiel des possibilités de l'outil de mesure d'audience de Google. Formation animée par les experts Google Analytics de Ranking Metrics.
Tous les détails sur le site Ranking Metrics : programme, prix, dates et lieux, inscription en ligne.
Lectures recommandées sur ce thème :
- [Résolu] Moteur de recherche interne et les accents
- PHP/Mysql: moteur de recherche interne
- moteur interne de recherche en perl ou php ?
- Gestion des accents pour un moteur de recherche PHP
- moteur de recherche interne ?
- moteur de recherche interne
- Un moteur de recherche interne sécure...
- Moteur de recherche interne (résolu)
- Moteur de recherche interne au site
- optimiser un moteur de recherche interne
Consultez la description détaillée des produits ou services de Google suivants : Google Custom Search Engine
Qui est en ligne
Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité
