Bonjour à tous.
Après un bout de temps a galérer sur ce problème " Incorrect string value: '\xC3' for column 'word' at row 1 "
J'en profite pour vous envoyer mon analyse
et une solution.
Les exemples ci dessous sont relatifs à l'envoi du content "
juq'à la" (" juq'à ")
La solution proposée est générique et résoudra pas mal de vos problèmes d'encodage.
Localisation du problème :
En regardant les trames reseaux SQL on voit que le problème vient effectivement de l’exécution du statement SQL
INSERT INTO epc_module_search_index (item_id, word, count) VALUES (1325,?,?)
En effet, lors du passage du tableau de mot, on obtient pour
juq'
Code :
6A 75 71 27 C3 01
j u q ' !! 1
-------------- --
le mot Nb occurence
C'est cela qui est responsable de la fameuse erreur 0xC3 ....
Mais quel est la source du probleme ?
0x27 en UTF8 est bien
'
mais 0xC3 n'est ni connu en UTF8 ni en LATIN.
Il faut donc comprendre pourquoi notre moteur php envoi un xC3 qui semble ne correspondre a rien..
..
On regarde le code responsable de la préparation du statement SQL:
search.tools.php.
On trouve ici la sequence responsable de la création du tableau de mots a indexer.
Code :
1) $content = html_entity_decode($content);
2) $stemmed_words = $obj->StemPhrase($content);
3) $tmp = array_count_values($stemmed_words);
Que se passe t'il avec un content de type
juq'à la
1) L’exécution de html_entity_decode
juq'à la -->
juq'à la
Par défaut l'encodage est utf8 et
à en UTF8 ça donne
xC3xA0
On obtient donc
Code :
x6A x75 x71 x27 xC3 xA0
j u q ' à
On commence a comprendre que
notre probleme semble venir d'un mauvais decoupage.
2) StemPhrase exécute en réalité search_StemPhrase (toujours dans
search.tools.php.)
La décomposition de la phrase en mots a lieu avec
Code :
$words = preg_split('/[\s,!.;:\?()+-\/\\\\]+/', $phrase);
Et la se trouve l'erreur ... (stackoverflow 15137660)
On a une difference entre Lunix et windows:
- Par defaut preg_split utilise l'encodage local (donc
pas UTF8 sur Windows).
- Mais html_entity_decode fournie de l'UTF8 !!!
Si en entrée on a du UTF8 (ce qui est notre cas ...) alors la correction est :
=> Rajouter /u a notre paramettre preg_split pour forcer un comportement en UTF8 sur preg_split
En resumé :
Certaines methodes PHP de traitement de texte ne s'alignent pas forcement sur default_charset.
On a ici un
html_entity_decode fera du UTF8 (car default_charset = UTF8)
Mais on a un
preg_split qui travail avec le charset local ... et donc n'arrivera pas a interpréter/splitter x27 xC3 xA0 correctement.
La solution:
Il faut modifier
modules\Search\search.tools.php
Code :
$words = preg_split('/[\s,!.;:\?()+-\/\\\\]+/', $phrase);
==>
$words = preg_split('/[\s,!.;:\?()+-\/\\\\]+/u', $phrase);
Note:
Depuis PHP 5.4.0 html_entity_decode fonctione bien par defaut en UTF8 ..
.... mais par acquis de conscience et afin d'eviter un plantage de cms madesimple sur un default_charset different de UTF8
Je recommanderais aussi de modifier
$content = html_entity_decode($content);
avec
$content = html_entity_decode($content,ENT_COMPAT | ENT_HTML401,UTF-8);