[Tuto] Encodage UTF-8

1 message   •   Page 1 sur 1
Avatar de l’utilisateur
ViPHP
AB
ViPHP | 5818 Messages

18 Déc 2008, 10:56

    Apache, php et mysql travaillent encore aujourd'hui par défaut avec la norme ISO-8859-1. L'inconvénient de cette norme est qu'elle utilise un encodage des caractères ou symboles sur un octet soit seulement 256 possibilités.

    C'est pour dépasser cette limite et pouvoir faire afficher par exemple des caractères français et chinois sur une même page qu'a été développé l'unicode et plus particulièrement l'UTF-8 très utilisé pour les applications Unix et Internet.

    L'UTF-8 peut encoder sur 1 à 4 octects et permet l'affichage de quasiment tous les caractères et symboles internationaux. La future version PHP6 adoptera cette norme par défaut.

    Cette norme possède néanmoins les inconvénients de ses avantages : pour gagner de la place en mémoire certains caractères seront encodés sur un octet alors que d'autres le seront sur deux (caractères accentués français par exemple) ou plus. Or de nombreuses fonctions php de recherche sur les chaines de caractères utilisent le nombre d'octets trouvés. Par exemple la fonction strlen('aé') retournera donc 3 sur une page codée en UTF-8 alors qu'elle est censée retourner la longueur de la chaine 'aé' soit une valeur attendue de 2.

    Il est donc important d'être homogène tout au long de la création de votre projet, de la configuration de vos outils de travail en UTF-8, à l'utilisation de fonctions adéquates au traitement des chaines multi-octets.

Configurer votre outil de travail
    Il est indispensable d'enregistrer vos fichiers en choisissant l'encodage UTF-8, par exemple :

    - Eclipse : Window > préferences > Géneral > WorkSpace > boite "Text file encoding"
    - Notepad++ : Paramétrage > Nouveau document. Pour modifier le document courant : Format > "Encoder en UTF8"
    - Zend Studio : Tools > Desktop > Apparence
    - Dreamweaver : Edition > Préférences > Nouveau document > Codage par défaut
    - Bloc notes window : Enregistrer sous > codage

    Dans tous les cas si cela vous est proposé, ne pas inclure une signature unicode BOM

Configuration des entêtes
    HTML
    Il vous suffit d'indiquer le charset dans une balise meta à la suite de la balise head

    Code : Tout sélectionner

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

    Cette ligne doit logiquement être la première suivant la balise <head> puisqu'elle indique au navigateur l'encodage utilisé.
    Attention, l'entête envoyée par le serveur sera prioritaire sur cette déclaration html


    APACHE
    Comme mentionné en préambule, le serveur apache envoie (généralement pour l'instant) des entêtes à la norme ISO-8859-1.
    - Si vous avez accès à la configuration du serveur > httpd.conf, ajoutez l'une ou l'autre des lignes

    Code : Tout sélectionner

    AddDefaultCharset UTF-8
    #ou
    AddDefaultCharset Off

    Avec la deuxième solution le serveur se renseigne sur l'entête http et sera donc en cohérence avec le charset indiqué dans la page html.

    - Sans accès à la configuration du serveur vous pouvez mettre l'une ou l'autre des lignes ci-dessus dans un fichier .htaccess

    - Si ces lignes ne sont pas prises en compte dans le fichier .htaccess, indiquez au début de vos pages php :
    [php]header('Content-Type: text/html; charset=UTF-8');[/php]
    Cette dernière solution plus universelle permet un meilleur portage de vos scripts.


PHP
    Configuration php.ini
    Le module "mbstring" s'occupe de la manipulation des chaînes tandis que le module "iconv" permet de convertir différents types d'encodages.
    Les conversions entre ISO et UTF-8 peuvent se réaliser à l'aide des fonctions utf8_encode() et utf8_decode().
    Dans la plupart des cas vous n'aurez pas à intervenir sur la configuration du php.ini.

    Utilisation des fonctions de traitement des chaines multi octets
    Pour reprendre l'exemple initial, mb_strlen() sera utilisée à la place de strlen().
    Liste des fonctions adaptées au traitement des chaines UTF-8

    PHP travaille pour l'instant en ISO, il faudra donc spécifier l'encodage utilisé pour les fonctions qui le demande ou modifier l'encodage initial.

    Typiquement :
    [php]echo mb_internal_encoding(); //affiche ISO-8859-1
    echo mb_strlen('aé');// affiche 3
    echo mb_strlen('aé',"utf-8");// affiche 2

    mb_internal_encoding("UTF-8");// indique d'utiliser l'encodage UTF-8
    echo mb_strlen('aé');// affiche 2[/php]


MySql
    Pour MySql comme pour toute autre base de donnée il est préférable de créer votre base en spécifiant l'encodage utf8_general_ci.
    Cette possibilité est cependant rarement disponible sur les serveurs mutualisés. Pour contourner ce problème et une meilleure portabilité de votre code, vous pouvez indiquer l'encodage à utiliser en envoyant la requête "SET NAMES UTF8" juste après la connexion à votre base.
    [php]mysql_select_db($database, $connection);
    mysql_query("SET NAMES 'utf8'");[/php]Pour les versions PHP 5 >= 5.2.3 et MySQL version 5.0.7 ou supérieure, utilisez de préférence mysql_set_charset


    Vos tables doivent également être créées en utilisant l'Interclassement utf8_general_ci via phpMyAdmin, ou dans une fenêtre sql :

    Code : Tout sélectionner

    CREATE TABLE IF NOT EXISTS `membres` (
      `pseudo` varchar(100) NOT NULL,
      `pass` varchar(100) character set utf8 collate utf8_bin NOT NULL,
      PRIMARY KEY  (`pseudo`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

    Dans cet exemple le champ "pass" est formaté avec "collate utf8_bin" pour être sensible à la casse.


Note
    Une fois tout configuré, il faut faire attention à ce que les éventuels anciens fichiers encodés en iso et appelés dans votre script soient également convertis et encodés en utf-8.


FAQ
    Problèmes d'affichage
    Si la page affiche des caractères de ce type : "é", "î", "Ã", ...
    => Les données ont été enregistrées au format UTF-8, et le navigateur les affiche en pensant avoir affaire à de l'ISO.

    Si la page affiche des caractères de ce type : "�"
    => Les données ont été enregistrées au format ISO, et le navigateur les affiche en pensant avoir affaire à de l'UTF-8.

    Si les données sont codées en dur dans la page, voir l'encodage de l'éditeur de texte, l'header apache et la balise meta "charset".
    Si les données proviennent de la base, vérifier le format de stockage et les méthodes de lecture et d'insertion (SET NAMES et charset).
    Si les données proviennent de l'extérieur (web services, rss, ...), penser à convertir les chaînes de caractère (utf8_encode-decode et fonctions du module iconv).

    Utilisation de fonctions pouvant poser problème avec les chaines multi octet
    Erreurs courantes
    - strtr() => utilisez str_replace()
    - htmlentities() => spécifiez le charset utf-8 ou mieux utilisez htmlspecialchars()
    - strpos(), strlen(), substr() etc. => utilisez les fonctions adaptées au traitement des chaines UTF-8
    - extension des expressions régulières notamment /i
    Consultez ce lien pour plus d'informations

    Migration d'un site ISO-8859-1 vers UTF-8
    En plus des conseils ci-dessus ce lien peut vous être utile


Exemple de code complet et fonctionnel réalisé en UTF-8 (php,mysql,html)
Dernière édition par AB le 18 Déc 2008, 11:19, édité 1 fois.

1 message   •   Page 1 sur 1