Je suis en train de mettre en place un nouveau serveur et je souhaite prendre en charge intégralement UTF-8 dans mon application Web. J'ai déjà essayé de le faire sur des serveurs existants et j'ai toujours été obligé de revenir à ISO-8859-1.
Où dois-je exactement définir l'encodage/les jeux de caractères ? Je suis conscient que je dois configurer Apache, MySQL et PHP pour ce faire. Existe-t-il une liste de contrôle standard que je peux suivre, ou peut-être dépanner les endroits où les incompatibilités se produisent ?
Il s'agit d'un nouveau serveur Linux, avec MySQL 5, PHP 5 et Apache 2.
Stockage de données :
utf8mb4
sur toutes les tables et colonnes de texte de votre base de données. Cela permet à MySQL de stocker physiquement et de récupérer des valeurs encodées nativement en UTF-8. Notez que MySQL utilisera implicitement l'encodage utf8mb4
si une collation utf8mb4_*
est spécifiée (sans jeu de caractères explicite).utf8
, qui ne supporte qu'un sous-ensemble de caractères Unicode. J'aimerais bien plaisanter.
Accès aux données :utf8mb4
. De cette façon, MySQL n'effectue aucune conversion de son UTF-8 natif lorsqu'il transmet les données à votre application et vice versa.charset
dans le DSN :
$dbh = new PDO('mysql:charset=utf8mb4' ;);set_charset()
] (http://php.net/manual/en/mysqli.set-charset.php) :
$mysqli->set_charset('utf8mb4' ;); // style orienté objet
mysqli_set_charset($link, 'utf8mb4' ;); // style procéduralmysql_set_charset
][2].SET NAMES 'utf8mb4'
.utf8mb4
/utf8
s'applique comme ci-dessus.
Sortie :default_charset
du php.ini, ou éditer manuellement l'en-tête MIME Content-Type
, ce qui représente plus de travail mais a le même effet.json_encode()
, ajoutez JSON_UNESCAPED_UNICODE
comme deuxième paramètre.
Entrée :mb_check_encoding()
fait l'affaire, mais vous devez l'utiliser religieusement. Il n'y a pas vraiment de moyen de contourner cela, car les clients malveillants peuvent soumettre des données dans l'encodage qu'ils veulent, et je n'ai pas trouvé d'astuce pour que PHP le fasse pour vous de manière fiable.accept-charset
à toutes vos balises <form>
: <form ... accept-charset="UTF-8">
.
Pour le HTML avant HTML5 seulement : notez que la spécification HTML du W3C dit que les clients "devraient" renvoyer par défaut les formulaires au serveur dans le jeu de caractères que le serveur a servi, mais ce n'est apparemment qu'une recommandation, d'où la nécessité d'être explicite sur chaque balise <form>
.
Autres considérations de code :mbstring
de PHP.mbstring
.En plus de définir default_charset
dans le php.ini, vous pouvez envoyer le bon jeu de caractères en utilisant header()
dans votre code, avant toute sortie :
header('Content-Type: text/html; charset=utf-8');
Travailler avec l'Unicode en PHP est facile tant que vous réalisez que la plupart des fonctions de la chaîne de caractères ne fonctionnent pas avec l'Unicode, et que certaines peuvent complètement déformer les chaînes de caractères. PHP considère que les "caractères" ; font 1 octet de long. Parfois, cela est correct (par exemple, explode()
ne cherche qu'une séquence d'octets et l'utilise comme séparateur - donc les caractères que vous recherchez n'ont pas d'importance). Mais d'autres fois, lorsque la fonction est réellement conçue pour travailler sur des caractères, PHP n'a aucune idée que votre texte contient des caractères multi-octets qui sont trouvés avec Unicode.
Une bonne bibliothèque à consulter est [phputf8][1]. Elle réécrit toutes les fonctions "mauvaises" pour que vous puissiez travailler en toute sécurité sur les chaînes UTF8. Il existe des extensions comme l'extension mbstring qui essaient de faire cela pour vous, aussi, mais je préfère utiliser la bibliothèque parce qu'elle est plus portable (mais j'écris des produits grand public, donc c'est important pour moi). Mais phputf8 peut utiliser mbstring en arrière-plan, de toute façon, pour augmenter les performances.
En PHP, vous devez soit utiliser les [fonctions multibytes][1], soit activer [mbstring.func_overload][2]. De cette façon, les fonctions comme strlen fonctionneront si vous avez des caractères qui prennent plus d'un octet.
Vous devrez également identifier le jeu de caractères de vos réponses. Vous pouvez soit utiliser AddDefaultCharset, comme ci-dessus, soit écrire du code PHP qui renvoie l'en-tête. (Ou vous pouvez ajouter une balise META à vos documents HTML).
[1] : http://us2.php.net/manual/en/ref.mbstring.php [2] : http://us2.php.net/manual/en/mbstring.configuration.php