21/03/2018, 11:51:22
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'
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.
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
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
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
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);
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);