PHP, MYSQL & UTF8

PHP MysqlSuite à une discussion via Twitter et ensuite par email, j’ai décidé de faire partager mon expérience de l’UTF8 avec PHP 5 et Mysql 5.

Comme première information, mais qui va conditionné tout le reste, PHP ne fonctionne actuellement qu’avec des chaines de caractères au format ISO. Toutes connexion vers le monde extérieures telle que vers MySql se fait donc en ISO par défaut.

Vous me direz alors à quoi sert les fonctions telles que UTF8_encode et decode ?
Tout simplement coder les caractères ISO en UTF8 … mais en les laissant dans une chaine au format ISO. Résultat, si on ne dit pas explicitement que la chaine est au format UTF8, on aura des caractères « bizarres ».

Oui mais, mon site est correcte, seule Phpmyadmin m’affiche ces fameux caractères bizarres, pourquoi ?
Nous avons vu que PHP gère de l’ISO, et qu’il se connecte par défaut en ISO à mysql.
Pour vérifier, il suffit d’un petite fonction php toute simple, mysql_client_encoding qui va retourner le codage utilisé par le client PHP pour se connecter à Mysql. Il vous retournera dans 99% des cas quelque chose du genre LATIN1.
Autre variable du problème, le codage des tables et surtout des champs dasn ceux-ci. Cas 1 : Si vous mettez UTF8, voici ce qu’il va se passer :

  • Le navigateur envoi des données au format l’UTF8.
  • PHP les reçoit et les mets dans une chaine de caractères.
  • PHP se connecte en ISO à mysql.
  • Mysql voit une connexion ISO et veux mettre à jour un champs UTF8.
  • Mysql va convertir se qu’il croit être de l’ISO en UTF8.

Et idem lors de l’affiche, le chemin est inversé, voilà pourquoi l’informations est bonne avec un script « normal ».

Cas 2 : Si la table est au format ISO, voici ce qu’il se passera :

  • Le navigateur envoi des données au format l’UTF8.
  • PHP les reçoit et les mets dans une chaine de caractères.
  • PHP se connecte en ISO à mysql.
  • Mysql voit une connexion ISO et des champs en ISO.
  • Mysql va copier l’information sans aucun changement.

Et toujours la même chose dans l’autre sens.

Oui, mais je ne comprends pas pourquoi Phpmyadmin m’affiche dans tous les cas une mauvaise information, alors qu’il est bien en UTF8 ?
Ici aussi c’est assez simple, Phpmyadmin étant amené à travailler avec tous types de format, chaque requête recupère l’information grâce au format de la table (Ce qui est logique). Il se connecte en UTF8, donc un champs en UTF8, sera retourné tout simplement, un champs ISO sera lui convertit en UTF8. Ce qui se passe avec un champs UTF8 ou l’information à été enregistré comme le décrit le cas 1, l’information UTF8 à été encodé une nouvelle fois en UTF8. Phpmyadmin affiche donc la bonne information au regard de la tâble.

Ou doit-on entre autre faire attention et renseigné qu’on est en UTF8 ?
Dans l’HTML, mais là ça dépends de la configuration du serveur web. On peut configurer pour qu’il envoie tout en UTF8. Mais rien n’empêche de dire explicitement sous quelle format est la page, c’est même mieux.
On doit aussi se connecter en UTF8 ou si ce n’est pas possible, dire que la session est en UTF8, et ceci grâce à la « requête » SET NAMES ‘UTF8’.

Vous faites ceci dans l’ordre :
$link = mysql_connect([host],[user],[password]);
mysql_select_db([database],$link);
mysql_query(« set names ‘utf8′ »,$link);

Avec ceci, plus de problèmes, la session sera en UTF8, donc toutes données envoyé seront en UTF8, et mysql ne fera plus aucun encodage. Phpmyadmin sera connecte, tout comme les valeurs réels dans la base de données.

Si vous avez tout bien compris, vous venez de comprendre que votre base de donnée contient de mauvaise information, et que pour utilisé cette technique, il vous faudra convertir celle-ci entièrement. Bon courage !


2 Comments

  • PaKaL

    05/05/2009

    Merci encore pour ton aide…

    Cela dit, ça ne m’empêche pas de penser qu’il y a encore pas mal de boulot coté uniformisation et que les solutions apportée reste de mon point de vue pas mal de chipotage… 🙂

    Reply
  • Tibius

    05/05/2009

    Ravi d’avoir pu aider, et vu la subtilité, autant la partagée 😉

    En effet, heureusement, PHP6 devrait gérer bien mieux l’UTF8 d’après ce que j’ai lu. Maintenant est de savoir comment ?!
    Mais bon, en prenant l’habitude de dire partout quelle langage on utilise, il ne devrait plus y avoir de gros problèmes 🙂

    Reply

Laisser un commentaire