Navigation

Contactez-nous

Kitpages
17 rue de la Frise
38000 Grenoble
tel : 04 58 00 33 81

Par Philippe Le Van (@plv) Dernière mise à jour : 26 March 2008

Basculer son site en UTF-8

Introduction

Si vous souhaitez coder un outil ou un site qui fonctionne avec des caractères ésotériques (Chinois, Arabe, Indien,...), vous devez changer la façon de coder vos caractères et de les transmettre sur le réseau. Cette façon de coder les caractères s'appelle le Charset. Le plus courant par nos latitudes est le charset ISO-8859-1. Il contient les caractères européens.

Pour écrire des textes en chinois, arabe, hébreux, indien, japonais... vous devez utiliser un charset qui permettent de coder tous les caractères de ces langues. Le charset le plus standard pour coder tout ça est UTF-8.

Le problème des charsets

Un charset, c'est une façon de coder un texte. Donc quand un script PHP parle avec une base de données, s'ils parlent avec le même charset, aucun problème. Par contre, s'ils parlent avec un charset différent, le message est mal transmis.

Le cas typique est la base qui parle en UTF-8 et PHP qui parle en ISO-8859-1. Les caractères de bases (lettres, chiffres), sont codés de la même façon dans ces deux charsets, ils sont donc transmis correctements. Par contre, tous les accents, ou caractères bizarres sont mal transmis. C'est pour ça qu'on a régulièrement les accents cassés quand on jongle entre UTF-8 et ISO-8859-1.

Le problème se situe à tous les niveaux :

  • PHP parle avec la base de données
  • Plusieurs librairies PHP parlent ensemble
  • PHP parle avec Apache
  • Apache parle avec le navigateur de l'internaute

Pour que tout se passe bien, il faut que tout ce petit monde se mette d'accord pour parler 2 à 2 dans le même charset...


Le plus simple est de dire : "ok messieurs, tout le monde parle UTF-8". Seulement ça ne marche pas toujours... certaines librairies ne fonctionnent qu'en ISO-8859-1, d'autre uniquement en UTF-8. Dans ce cas, il faut assurer les conversions entre les 2 charsets dans les 2 sens pour tout ce qu'on envoie ou qu'on reçoit depuis cette librairie...

Hum... J'ai perdu 80% des lecteurs ? Tant pis, je persiste...

Démarche à suivre

Ce tutoriel donne la démarche à suivre pour basculer l'ensemble de son site en UTF-8. Il y a beaucoup d'étapes, c'est compliqué, mais une fois que c'est fait, on est tranquille jusqu'à la nuit des temps...

Ce paragraphe donne juste les étapes qui sont détaillées en dessous :

  • Convertir vos fichiers PHP, config, html,... en UTF-8
  • Changer le code HTML pour déclarer le nouveau charset
  • Changer le header HTTP pour déclarer le nouveau charset (config apache ou header PHP)
  • Changer le charset de connexion à la base de données
  • Changer l'encodage des tables de votre base de données
  • Changer les fonctions de string PHP en fonctions mb_string dans votre code
  • Configurez vos librairies pour qu'elles papotent en UTF-8 si elles le peuvent
  • Lister les librairies qui ne fonctionnent qu'en ISO-8859-1 et faire les conversions qui vont bien avant de les appeler et après avoir reçu leurs réponses (attention, avec ces librairies, vous ne pourrez pas afficher de caractères chinois par exemple).

Convertir les fichiers en UTF-8

Vous devez convertir vos fichiers en UTF-8 : quand un fichier texte est enregistré sur un disque dur, il est enregistré avec un certain charset. Par défaut, Windows utilise par défaut un charset proche de ISO-8859-1 (Windows-1252). Par contre un éditeur de texte un peu évolué dispose d'options qui vous permettent de sauvegarder vos fichiers en UTF-8.

Ca ne pose pas de problème que votre système soit dans un charset différent de vos fichiers, tant que votre éditeur de texte peut éditer dans le charset de votre code...

Bref voilà 2 solutions simples pour transformer un code ISO-8859-1 en code UTF-8 :

  • Si vous utilisez eclipse, changez le charset de votre projet (clic droit sur le projet > properties > info et choisissez UTF-8 comme charset du projet). Il se charge de tout convertir
  • Si vous êtes sous unix, vous pouvez utiliser la commande iconv (je vous laisse vous reporter à la doc, perso, j'utilise Eclipse )

 

Changer le code HTML pour déclarer le charset

Vous devez déclarer le charset dans le HEAD de votre code HTML.

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Changer le header HTTP renvoyé au navigateur

Le header HTTP doit également être modifié pour déclarer qu'on est en UTF-8.

Vous pouvez dire à apache de déclarer de l'UTF-8 par défaut en ajoutant dans httpd.conf (dans votre virtualHost)

  • AddDefaultCharset UTF-8

Si vous n'avez pas acces à la conf apache, vous pouvez imposer le charset d'une page avec la commande ci-dessous :

<?php
header('Content-Type: text/html; charset=utf-8');
?>

Connexion à la base de données

Pour que la communication entre PHP et Mysql soit en UTF-8 vous devez lancer la requête suivante avant n'importe quelle autre requête :

SET NAMES UTF8

Changer l'encodage des tables de votre BDD

Les tables de votre base de données doivent être en UTF-8 sinon vous ne pourrez pas sauvegarder les caractères internationnaux. Notons cependant que le charset des tables n'a pas de rapport avec le charset utilisé par la communication entre PHP et Mysql.

Notons que dans l'exemple ci-dessous, nous indiquons que le charset des tables est UTF-8, et la collation utilisée est utf8_bin qui permet de faire des comparaisons "case sensitive".

Je vous renvoie vers la doc Mysql pour plus de détail sur les collations : http://dev.mysql.com/doc/refman/5.0/fr/charset-general.html 

ALTER TABLE `table_name`  DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

Utiliser les fonctions mb_string de php

Si les librairies que vous utilisez peuvent discuter en UTF-8, il faut leur dire que vous parlez en UTF-8.

Prenons juste en exemple avec le Zend Framework, si vous voulez utiliser des vues en UTF-8, il faudra utiliser le code suivant :

<?php
$view->setEncoding('utf-8');
?>

Les libs qui ne supportent pas UTF-8

Pour les librairies qui ne supportent pas UTF-8. il faut

  • utiliser utf8_decode sur chaque paramètre qu'on envoie à cette librairie
  • utiliser utf8_encode sur chaque paramètre qu'on reçoit de cette librairie

Conclusion

Le sujet est assez complexe. Il y a certainement quelques erreurs dans ce tutoriel, n'hésitez pas à m'en faire part dans les commentaires.

J'espère que ce tutoriel va vous aider à basculer vos site en UTF-8 quand vous en aurez besoin.

Commentaires

Note : on ne peut plus ajouter de commentaire sur ce site
Sauvé !
Après plusieurs jours de galère je tombe sur ces commentaires et hop mon pb de caractère est résolue : c'est bien dans les vieux post que l'on trouve parfois la solution.

Merci
PDO - MySQL
> 1ère façon :
$bdd = new PDO('mysql:host=localhost;dbname=tst1;charset=utf8', 'root', 'root');

> 2ème façon : 
$bdd = new PDO('mysql:host=localhost;dbname=tst1', 'root', 'root'); 
$bdd->query('SET NAMES UTF8');

Les 2 ont l'air de marcher ... je découvre hein, prenez le comme il se doit :)
ADOdb + Oracl
En utilisant la librairie ADOdb et pour une connexion Oracle, il faut ajouter :

$conn->charSet = 'UTF8';

juste avant

 $conn->Connect(...);
Notepad++
Dans le menu "Encodage" sélectionné convertir en utf-8 sans BOM
Re: Notepad++
Hum... aucune idée, je n'ai jamais utilisé Notepad++, mais il y a certainement dans les options quelque chose qui permet de changer l'encodage des fichiers. Cherche du coté de "encoding", "charset"...
Notepad++
Et Notepad++, comment fait-on ?