CactusCrew

CactusCrew
 
La ronde des Charsets

Une explication sur les différents endroits où une chaîne de caractère peu perdre son charset, et donc être corrompue.

Intro

Il arrive bien souvent d'être confronté à des problèmes d'encodage de caractères lorsque l'on bascule une appli web d'un serveur à un autre.
Et celà devient vite compliqué de voir à quelle endroit la donnée est corrompue.
Nous allons donc inspecter ces différents points, et en prendre note pour nos futures applications web :

  1. Charset des fichiers PHP, config, html, template...
  2. Charset indiqué dans le code (x)HTML
  3. Header HTTP déclarant le charset (config apache ou header PHP)
  4. Le charset de connexion à la base de données
  5. Encodage des tables de la base de données
  6. Abandonner les fonctions string PHP au profit des fonctions mb_string (pour les charsets de type UTF-8)
  7. Configuration du charset des librairies (Zend, PEAR...)
  8. Lister les librairies qui ne fonctionnent qu'avec un charset en particulier et faire les conversions qui vont bien avant de les appeler et après avoir reçu leurs réponses.

Sachant qu'il faut utiliser le même encodage à tout les étages.
De plus, je privilégie l'usage de l'UTF-8 comme encodage, pour des raisons évidentes de portabilité et de traduction dans n'importe quel alphabet.

1 Charset des fichiers PHP, config, html, template

Tous les fichiers utilisé dans votre appli doivent être encodé avec le même jeu de caractère :
Dans Zend et Eclipse, vous pouvez spécifier l'encodage de caractère du projet.
Sinon, sous Linux, vous pouvez utiliser la commande iconv.

2 Charset indiqué dans le code (x)HTML

Prenez soin d'ajouter ceci dans l'entête html de votre page :

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
3 Header HTTP déclarant le charset (config apache ou header PHP)

Si vous avez accès à la configuration d'Apache, regardez si vous avez une directive spécifiant l'encodage par défaut des transmissions HTTP : AddDefaultCharset UTF-8.
Sinon, et que je conseille pour un meilleur portage d'une appli (car indépendant de la configuration du server), c'est d'indiquer ceci dans le code PHP :

header('Content-Type: text/plain; charset="UTF-8"');
4 Le charset de connexion à la base de données

C'est certainement une des méandres les moins connues, et pourtant, elle mérite le coup d'oeil : le charset de la connexion entre PHP et MySQL. Sur la connexion active, spécifiez concrêtement l'encodage de dialogue via cette requête :

SET NAMES UTF8
5 Encodage des tables de la base de données

C'est un peu plus connu, mais il faut y faire attention à bien spécifier l'encodage à utiliser lors de la création des tables.

CREATE TABLE `toto` (
    ...
) DEFAULT CHARSET=utf8;

Ou bien convertir les données d'une table existante :

ALTER TABLE `toto`  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

A savoir que dans nos contrée européennes, l'encodage par défaut de MySQL est le latin1 qui correspond au ISO-8859-1.

6 Utiliser les fonctions mb_string

Ne plus utiliser les functions string de base. Elles sont en effet, non pas incapables, mais hazardeuses si l'on souhaite travailler avec des charsets plus évoluées, tel qu'UTF-8.
Il faut utiliser les fonctions pour les chaînes de caratères multi-octets. mb_string et compagnie.

7 Configuration du charset des librairies

Si c'est possible configurer, indiquer l'encodage de travail.
Exemple avec le moteur de vues du Zend Framework :

<?php
$view->setEncoding('utf-8');
?>
8 Cas des librairies non configurables

Si on ne peux pas configurer la librairie, il "suffit" juste de filtrer les entrées/sorties, avec utf8_encode/utf8_decode.

Conclusion

Si vous suivez pas à pas ces pistes, vous devriez avoir une appli correctement configurée pour être portable, et oubliés vos ennuis d'encodages !

 
PDF
« retour à l'accueil
Commentaires
1.   Tatane  |  jeudi 31 mai 2007 à 14:38

Attention que ds les encodages utf8_bin par colonne ne te permettent plus de faire du SELECT sensible à la casse ...
il te faudra donc convertir tout en majuscules ou minuscule savant le SELECT ...

je parle par expérience récente ;-)

 
2.   Nicolas SUPRIN  |  mardi 5 juin 2007 à 11:13

Je suppose que tu veux dire que c'est dans le cas d'un SELECT ... WHERE ... LIKE '%%'... ?

Et donc une solution pour etre insensible a la casse serait de faire un

SELECT UPPERCASE(table.champ) as upperchamp FROM table WHERE upperchamp LIKE '%toto%'
 
3.   Nicolas SUPRIN  |  vendredi 8 juin 2007 à 09:50

Solution, pour rester insensible à la casse, il faut utiliser l'encodage utf8-unicode-ci
Merci à Tatane qui remercie Béryl

 
« retour à l'accueil
Trackbacks

Aucun trackback.

Les trackbacks pour ce billet sont fermés.

 
Ajouter un commentaire

Les commentaires pour ce billet sont fermés.