Utiliser UTF-8… pourquoi ?
L’essor d’Internet et les tendances à la globalisation s’accompagnent des phénomènes suivants :
- mise à disposition d’extranets au niveau mondial ;
- internationalisation des sites ;
- mise à disposition de contenus ou de services à des parcs d’utilisateurs, de développeurs ou de clients hétérogènes dispersés dans le monde entier, et équipés de terminaux très divers (PC, Mac, téléphones portables).
L’internationalisation d’un site est souvent une étape cruciale, et souvent assez douloureuse si elle n’est pas préparée. Voici quelques exemples :
- des sites développés en Europe (en ISO-8859-1) se retrouvent à être complétés ou repris au Japon !
- les outils et claviers ne sont évidemment pas les mêmes selon le type d’alphabet utilisé, etc.
- l’ouverture du site à de nouveaux clients expose le serveur au risque de devoir interpréter des requêtes en provenance de formulaires dans des jeux de caractères non prévus dans le projet initial,
- les propres outils de développement peuvent varier dans la même entreprise, selon la localisation des différentes succursales,
Ajoutez à cela que même avec beaucoup de bonne volonté et en parlant la même langue, il est parfois difficile de se comprendre d’un continent à un autre… alors imaginez des machines à la place, et vous aurez une bonne idée de la complexité de la tâche !
Toutefois, plusieurs efforts de standardisation ont été menés, notamment Unicode, et UTF-8 (UCS transformation format 8 bits) découle de cette standardisation :
- il permet de représenter les caractères Unicode…
- …tout en étant compatible avec le vénérable ASCII, ce qui permet de limiter les difficultés,
- il est très bien géré dans la plupart des navigateurs récents,
- il fonctionne avec bon nombre d’éditeurs de code (sur différentes plateformes),
- et il est raisonnable en occupation mémoire.
Comme tous les standards qui permettent d’uniformiser l’accès à l’information et de faciliter la compatibilité entre machines, UTF-8 présente un intérêt majeur sur Internet. Et en effet, dans tous les cas précédents, l’adoption d’UTF-8, jeu de caractères universel par excellence permet d’améliorer la compatibilité des sites au niveau international.
Éléments à prendre en considération
Pour comprendre la relative complexité (au début, on imagine que ce n’est qu’une ligne « meta
» à changer), il faut avoir à l’esprit une chose que je vais essayer de vulgariser au mieux : le codage des données est en quelque sorte la « langue » dans laquelle les différents « intervenants électroniques » (base de données, serveur, etc.) vont traduire les 0 et les 1 qu’ils s’échangent, pour vous les afficher de manière intelligible.
Pour plus d’informations à ce sujet, je vous renvoie lire l’article d’introduction aux jeux de caractères.
Pour l’utilisateur, c’est assez simple : le navigateur et le site à afficher doivent se comprendre. Le site envoie du code correctement dans un jeu de caractères donné, et le navigateur l’affiche.
Pour le développeur du site, c’est un petit peu plus complexe. Prenons un cas concret assez classique : un site en XHTML/CSS/Javascript, écrit avec PHP/MySQL et hébergé sur un serveur Apache.
Partons de l’idée somme toute naturelle que tout le monde va devoir parler la même langue, l’UTF-8 donc. C’est là que le tout se complique, il y a plusieurs acteurs « électroniques » dans cette « discussion » pour faire tourner un site :
- le serveur qui fait tourner notre site, Apache dans notre exemple,
- la base de données, MySQL pour notre cas,
- le langage dynamique, PHP en l’occurrence,
- le langage qui structure le contenu pour le navigateur, ici XHTML,
- et les fichiers du site.
L’idée est de faire discuter chacun dans la même langue afin qu’ils se comprennent dès qu’ils échangent des données entre eux… et dès qu’ils en fournissent !
Si l’on part de zéro, bien évidemment, c’est plus facile : on choisit des outils (logiciels, bibliothèques, etc.) qui savent gérer l’UTF-8, on prend directement un SGBD (Système de Gestion de Base de Données) qui a cette capacité, etc. Bref, le cahier des charges sera prévu en fonction de cette contrainte.
Toutefois, nous nous plaçons dans le pire des cas, où il faut « migrer » un site qui n’a pas été conçu dans cette optique.
Bien sûr, la première chose à faire sera de tout sauvegarder ! Bases de données, fichiers, il faut y aller franchement, cela ne coûte presque rien et peut éviter quelques couacs durant la transition.
Comme un court exemple est bien plus efficace qu’un long discours, voyons les modifications à apporter à notre site exemple !
Serveur
Première chose à changer, dire à notre serveur Apache de nous « donner » de l’UTF-8 car cela n’est pas le cas par défaut. Si vous avez accès à la configuration d’Apache, il faudra remplacer
AddDefaultCharset ISO-8859-1
par
AddDefaultCharset UTF-8
Si vous n’avez pas accès à la configuration d’Apache, cette étape se résume alors à modifier l’entête HTTP (header
) envoyé par défaut par le serveur, cela peut se faire soit via PHP, soit via un fichier .htaccess
.
Via PHP :
<?php header("Content-Type: text/html; charset=UTF-8"); ?>
si vous servez votre site comme text/html
ou via :
<?php header('Content-Type: application/xhtml+xml;charset=UTF-8'); ?>
si vous servez votre site comme application/xhtml+xml
.
Via un fichier .htaccess
, par exemple :
AddDefaultCharset UTF-8 AddCharset UTF-8 .html
Attention, un fichier .htaccess
affectera non seulement tous les fichiers du répertoire dans lequel il se trouve, mais également tous les sous-répertoires !
Base de données
Il faut savoir que MySQL peut gérer le codage des données (la langue dans laquelle elles sont « adaptées »), et l’interclassement (la collation en anglais) : comment se comporter avec ces données (comment « comparer » un « é » et un « e », comment gérer la casse, etc.).
En quelque sorte, les règles de la « langue » choisie, pour reprendre l’analogie.
Là, c’est simple, il suffit de changer le codage et l’interclassement pour toute la base.
ALTER DATABASE nomDeLaBase CHARACTER SET UTF8 ;
(la base)ALTER TABLE nomDeLaTable CHARACTER SET UTF8 ;
(la table)ALTER TABLE nomDeLaTable CONVERT TO CHARACTER SET UTF8 ;
(les colonnes de la table)
Exemple plus « visuel » : en supposant qu’on ait phpMyAdmin, il suffit d’aller dans « operations » (pour la base et pour chaque table), et changer l’interclassement. Ensuite, il faut également faire de même pour chaque champ le nécessitant (exemple, des champs de type texte).
Pour ma part, j’ai pris utf8-general-ci
pour notre exemple : notre site n’a pas besoin d’être sensible à la casse dans MySQL (un « E » sera égal à un « e » dans une comparaison MySQL), d’où le ci
(case insensitive en anglais).
Pour information, utf8-general-cs
veut donc dire case sensitive, et utf8-general-bin
signifie un classement binaire, donc pas d’ordre linguistique à proprement parler.
Attention, cela ne veut pas dire que notre site ne gérera pas les majuscules ou les minuscules (rien à voir), cela « explique » à MySQL (et à MySQL uniquement) comment « appréhender » ces données !
À noter, si vous voulez forcer MySQL à utiliser l’UTF-8, il suffit de lancer cette requête avant toute autre à chaque fois :
SET NAMES 'utf8';
Mise à jour : cette requête fonctionnait avec la fonction mysql_query
, cette fonction étant dépréciée, il faudra se tourner vers l’équivalent en mysqli
ou PDO_MySQL
. Pour mysqli
, cela donne par exemple :
/* en objet */ if (!$mysqli->set_charset("utf8")) { printf("Erreur lors du chargement du jeu de caractères utf8 : %s\n", $mysqli->error); }
ou
/* en procédural */ if (!mysqli_set_charset($link, "utf8")) { printf("Erreur lors du chargement du jeu de caractères utf8 : %s\n", mysqli_error($link)); }
Sans rentrer dans les détails, cette requête « magique » aura le bonheur au passage de dire à MySQL de tout convertir, interpréter et envoyer en UTF-8, donc n’ayez vraiment pas peur de vous en servir. Attention, l’utilisation de cette requête indiquera qu’on se connectera, qu’on enverra et qu’on recevra des données en UTF-8 de la part de MySQL. Cela peut créer des petits soucis avec PHP, comme expliqué ci-dessous.
Le langage dynamique : PHP
Pour PHP… c’est un peu plus compliqué : PHP travaille nativement en ISO, ce n’est qu’à partir de la version 6 qu’il basculera entièrement en UTF-8.
Deux modules permettent de gérer différents types de codages, mbstring
et iconv
.
Le module mbstring
s’occupe de la manipulation de chaînes tandis qu’iconv
permet de convertir différents types de codage. Les conversions entre ISO et UTF-8 peuvent se réaliser à l’aide des fonctions utf8_encode()
et utf8_decode()
, qui vont bien souvent vous sauver la mise.
Un exemple simple : supposons qu’un sous-domaine (indépendant de notre projet) prenne néanmoins des données dans cette base récemment convertie en UTF-8.
Pour des contraintes de temps, d’argent, etc., il n’est pas possible de passer entièrement ce sous-domaine en UTF-8. Il nécessite pourtant des données en ISO-8859-1.
Or elles arrivent en UTF-8 depuis la base : l’affichage des données sur ce sous-domaine va poser des problèmes.
Pour reprendre l’analogie linguistique : c’est comme si une entreprise choisit l’anglais comme langue officielle interne, et qu’un département de cette société est uniquement francophone. Le temps d’apprendre l’anglais pour ce département, il faut en quelque sorte des traducteurs le temps de l’apprentissage !
L’utilisation de utf8_decode()
nous permettra d’afficher ces données de manière lisible à moindre effort, sans « é » à la place de certains caractères accentués.
Attention aux bibliothèques de code et aux fonctions de traitement de
caractères qui ne travaillent qu’en ISO, il faut les traiter avec le plus grand soin, si vous ne voulez pas avoir de grosses surprises !
XHTML
Le bout du tunnel se rapproche… pour XHTML, c’est assez simple dans notre cas :
<?xml version="1.0" encoding="UTF-8" ?>
pour le prologue XML ainsi que
<meta http-equiv="Content-Type" content="application/xhtml+xml;" />
pour indiquer au navigateur un type MIME application/xhtml+xml
ou
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
pour le servir en classique text/html
.
Si vous utilisez un doctype
HTML5, cela se fera avec :
<meta charset="utf-8" />
à positionner le plus haut possible dans votre head
.
Fichiers du site
Il reste enfin à s’occuper des fichiers du site. Eux aussi doivent être codés en UTF-8, notamment pour que le texte écrit « en dur » dans les pages soit bien retranscrit, étant donné que tout le site va parler dans « la langue » UTF-8. Les fichiers doivent donc également s’y plier.
Là, il vous suffit de trouver un éditeur de code qui gère cela, beaucoup le permettent. Notepad++ (sous Windows) le fait par exemple très bien, et peut même convertir vos fichiers d’un codage à l’autre. Des outils plus automatiques permettent de coder des fichiers à la volée.
Attention, certains éditeurs spécifient en début de fichier un marqueur d’ordre des octets (BOM, Byte-Order Mask en anglais). C’est inutile pour l’UTF-8, et même dangereux : le fait d’insérer ce caractère au début d’un fichier php (donc avant la balise d’ouverture de php) pourra provoquer une erreur du type « headers already sent »… à fuir de toute urgence !
Du côté des fichiers externes (Javascript et CSS), il est logique de coder également les fichiers en UTF-8 afin de continuer dans notre optique « tout UTF-8 ». Cette pratique n’est pas totalement entrée dans les mœurs pour une raison simple : les éléments XHTML sont en anglais et donc sont dépourvus d’accents dans la CSS. De la même manière, on code en anglais en Javascript.
Comme ASCII et UTF-8 ont un « tronc commun », les problèmes de codage des données ne sautent pas aux yeux !
Qui peut le plus peut le moins : autant s’assurer la tranquillité d’esprit que les commentaires (par exemple) soient bien retranscrits.
Pour déclarer le jeu de caractères de ces fichiers, on peut reprendre l’idée du fichier .htaccess
, par exemple :
AddCharset UTF-8 .js AddCharset UTF-8 .css
Pour les CSS, on peut aussi utiliser la « at-rule » @charset
, il suffit de l’indiquer au tout début de votre CSS (avant tout caractère) :
@charset "UTF-8";
Attention, cela n’a de sens que pour une CSS externe, et ne doit pas être utilisé pour des styles inclus directement dans les documents.
La plupart des éditeurs récents gèrent bien ce jeu de caractères, donc pas trop de souci à vous faire ce côté-là. L’idéal étant que tous les éditeurs utilisés pour le développement ou les mises à jour reconnaissent et traitent correctement les fichiers en UTF-8… ainsi on évitera de fâcheux problèmes de codage qui peuvent entraîner… de fâcheux problèmes d’affichage !
Conclusion
On peut constater que le passage à l’UTF-8 s’il n’a pas été prévu dés le départ n’est pas complètement anodin. Il faut donc autant que possible prévoir cette option en amont des projets… Un site peut se retrouver rapidement confronté à cette contrainte d’internationalisation, et il ne serait pas sérieux de se retrouver complètement bloqué à cause de ce genre de problème !
D’ailleurs, la plupart des projets collaboratifs (forums, CMS, etc.) s’y sont mis… ce n’est pas pour rien !
Références
- Introduction aux jeux de
caractères. - Article Unicode sur Wikipedia.
- Article UTF-8 sur Wikipedia.
Vos commentaires
# Kovsky Le 23 décembre 2010 à 17:30
Merci beaucoup, clair, bien expliqué. Tout ce que je cherchais.
^__^
# Med Le 25 août 2011 à 03:29
Merci pour votre article , il est très pertinent , c’est exactement ce que dont j’avais besoin . Bonne continuation .
# Xavier Le 7 décembre 2011 à 18:52
Merci beaucoup pour cet article. Il ne me reste plus qu’à m’y mettre en suivant vos précieux conseils...
# Vivien Blasquez Le 3 janvier 2012 à 23:17
Merci pour ce concentré d’informations. Tant que possible j’essaie de passer toutes mes pages et bases de données en UTF-8, mais il existe souvent des données qui échappent à la règle, comme le formatage par défaut des pages html ou php lors de leur création.
Le format est en tout cas plus confortable et "internationalisable".
Cordialement, Vivien Blasquez, développeur web
# aureg Le 5 mars 2012 à 15:57
Un tout grand merci pour cet article extrêmement complet, il m’a permis de régler les derniers problèmes de migration de mes pages PHP d’ISO vers UTF8.
La partie sur l’utilisation des BDD m’a été très utiles.
Ce site reste une mine d’or pour les développeurs WEB :-)
Aurélien http://blog.aureg.be
# Alain Le 6 juillet 2012 à 11:31
Bonjour,
J’ai transféré mon site http://www.lejoaillier.be depuis la version en ligne vers une version locale avec succès.
J’utilise Wamp server et tout fonctionne bien.
Je n’ai qu’un seul problème.
Alors qu’en ligne ils s’affichent parfaitement bien, en local Certains caractères accentués (le signe € dans les produits , ainsi que le "ç" de français dans mon sélecteur de langue s’affichent comme ceci "�".
Une idée ?
Merci.
# Thierry Le 20 janvier 2013 à 09:07
Bonjour,
Merci pour les informations.
J’ai converti mes tables et champs en UFT-8. Néanmoins, lorsque j’ai directement dans mysql des caractères avec accents, mon site ne me les restitue pas correctement (losange avec ?).
Est ce normal ?
Merci
Thierry
# Nicolas Hoffmann Le 21 janvier 2013 à 10:52
Bonjour,
voici une page rapide de diagnostic des problèmes UTF-8. Cela devrait vous aider.
De rien,
Nicolas
# blanco Le 15 mai 2014 à 11:27
après une longue recherche sur internet enfin un article qui vas a l’essentiel.
merci
Vos commentaires
Suivre les commentaires : |