utf8 - tag html php




UTF-8 tout au long de (10)

Bon objectif à avoir dès le début - en fonction de la nature de votre site, j'ai trouvé beaucoup de ressources à ce sujet par Googling - vous n'êtes pas le premier à le faire, bien sûr.

Le mystique PHP6 est censé avoir tout redressé, n'est-ce pas?

Vous pouvez presque définir utf-8 comme le jeu de caractères par défaut global pour mysql au niveau du serveur et il sera par défaut correctement aux niveaux plus granulaires.

Je suis en train de mettre en place un nouveau serveur, et je veux soutenir complètement UTF-8 dans mon application web. J'ai essayé dans le passé sur des serveurs existants et je devais toujours revenir à ISO-8859-1.

Où dois-je exactement définir l'encodage / les jeux de caractères? Je suis conscient que j'ai besoin de configurer Apache, MySQL et PHP pour cela - y a-t-il une liste de contrôle standard que je peux suivre, ou peut-être dépanner où les discordances se produisent?

C'est pour un nouveau serveur Linux, exécutant MySQL 5, PHP 5 et Apache 2.


Dans mon cas, j'utilisais mb_split , qui utilise regex. Par conséquent, j'ai également dû manuellement vérifier que l'encodage de regex était utf-8 en faisant mb_regex_encoding('UTF-8');

En guise de remarque, j'ai également découvert en exécutant mb_internal_encoding() que le codage interne n'était pas utf-8, et j'ai changé cela en exécutant mb_internal_encoding("UTF-8"); .


En plus de définir default_charset dans php.ini, vous pouvez envoyer le jeu de caractères correct en utilisant header() depuis votre code, avant toute sortie:

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

Travailler avec Unicode en PHP est facile tant que vous vous rendez compte que la plupart des fonctions de chaîne ne fonctionnent pas avec Unicode, et que certaines peuvent altérer complètement les chaînes . PHP considère que les "caractères" ont une longueur de 1 octet. Parfois cela est correct (par exemple, explode() recherche uniquement une séquence d'octets et l'utilise comme séparateur - peu importe les caractères réels que vous recherchez). Mais d'autres fois, lorsque la fonction est réellement conçue pour fonctionner sur des caractères , PHP n'a aucune idée que votre texte contient des caractères multi-octets trouvés avec Unicode.

Une bonne bibliothèque à vérifier est phputf8 . Cela réécrit toutes les «mauvaises» fonctions afin que vous puissiez travailler en toute sécurité sur les chaînes UTF8. Il y a des extensions comme l'extension mbstring qui essaye de faire ça aussi pour vous, mais je préfère utiliser la librairie 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 coulisse, de toute façon, pour augmenter les performances.


J'ai récemment découvert que l'utilisation de strtolower() peut entraîner des problèmes lorsque les données sont tronquées après un caractère spécial.

La solution était d'utiliser

mb_strtolower($string, 'UTF-8');

mb_ utilise MultiByte. Il supporte plus de caractères mais en général il est un peu plus lent.


Je voudrais ajouter une chose à l'excellente réponse de Chazomaticus :

Ne pas oublier la balise META non plus (comme ceci, ou la version HTML4 ou XHTML ):

<meta charset="utf-8">

Cela semble trivial, mais IE7 m'a donné des problèmes avec cela avant.

Je faisais tout bien. la base de données, la connexion à la base de données et l'en-tête HTTP Content-Type étaient tous définis sur UTF-8 et fonctionnaient parfaitement dans tous les autres navigateurs, mais Internet Explorer insistait toujours sur l'utilisation de l'encodage «Western European».

Il s'est avéré que la balise META manquait à la page. Ajoutant cela a résolu le problème.

Modifier:

Le W3C a en fait une section plutôt importante dédiée à I18N . Ils ont un certain nombre d'articles liés à ce problème - décrivant le côté HTTP, (X) HTML et CSS des choses:

Ils recommandent d'utiliser à la fois l'en-tête HTTP et la balise méta HTML (ou déclaration XML dans le cas de XHTML servi en XML).


La meilleure réponse est excellente. Voici ce que j'ai dû faire sur une installation régulière de debian / php / mysql:

// storage
// debian. apparently already utf-8

// retrieval
// the mysql database was stored in utf-8, 
// but apparently php was requesting iso. this worked: 
// ***notice "utf8", without dash, this is a mysql encoding***
mysql_set_charset('utf8');

// delivery
// php.ini did not have a default charset, 
// (it was commented out, shared host) and
// no http encoding was specified in the apache headers.
// this made apache send out a utf-8 header
// (and perhaps made php actually send out utf-8)
// ***notice "utf-8", with dash, this is a php encoding***
ini_set('default_charset','utf-8');

// submission
// this worked in all major browsers once apache
// was sending out the utf-8 header. i didnt add
// the accept-charset attribute.

// processing
// changed a few commands in php, like substr,
// to mb_substr

c'était tout !


Le support Unicode en PHP est toujours un énorme gâchis. Bien qu'il soit capable de convertir une chaîne ISO8859 (qu'il utilise en interne) en utf8, il n'a pas la capacité de fonctionner avec des chaînes Unicode en mode natif, ce qui signifie que toutes les fonctions de traitement de chaînes altéreront et corrompront vos chaînes. Vous devez donc soit utiliser une bibliothèque séparée pour le support approprié de utf8, soit réécrire vous-même toutes les fonctions de gestion de chaîne.

La partie facile est juste en spécifiant le jeu de caractères dans les en-têtes HTTP et dans la base de données et ainsi de suite, mais rien de tout cela n'a d'importance si votre code PHP ne sort pas un UTF8 valide. C'est la partie difficile, et PHP ne vous aide pratiquement pas là-bas. (Je pense que PHP6 est censé résoudre le pire de tout ça, mais c'est encore loin)


Si vous voulez que le serveur MySQL décide du jeu de caractères, et pas de PHP en tant que client (ancien comportement, préféré, à mon avis), essayez d'ajouter skip-character-set-client-handshake à my.cnf , sous [mysqld] , et redémarrez mysql .

Cela peut causer des problèmes si vous utilisez autre chose que UTF8.


Vieux sujet, je sais. Trouvé un problème avec quelqu'un utilisant PDO et la réponse était d'utiliser ceci pour la chaîne de connexion PDO:

$pdo = new PDO(
    'mysql:host=mysql.example.com;dbname=example_db',
    "username",
    "password",
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

Le site que j'ai pris est en panne, a été en mesure de l'obtenir en utilisant google cache heureusement.


Stockage de données

  • Spécifiez le utf8mb4 caractères utf8mb4 sur toutes les tables et colonnes de texte de votre base de données. Ceci fait que MySQL stocke et récupère physiquement les valeurs codées nativement en UTF-8. Notez que MySQL utilisera implicitement le codage utf8mb4 si un utf8mb4_* est spécifié (sans aucun jeu de caractères explicite).

  • Dans les anciennes versions de MySQL (<5.5.3), vous serez malheureusement obligé d'utiliser simplement utf8 , qui ne supporte qu'un sous-ensemble de caractères Unicode. Je voudrais que je plaisante.

Accès aux données

  • Dans votre code d'application (par exemple PHP), quelle que soit la méthode d'accès à la base de données que vous utilisez, vous devez définir le jeu de caractères de connexion sur utf8mb4 . De cette façon, MySQL ne fait aucune conversion à partir de son UTF-8 natif lorsqu'il transmet les données à votre application et vice versa.

  • Certains pilotes fournissent leur propre mécanisme de configuration du jeu de caractères de connexion, qui met à jour son propre état interne et informe MySQL de l'encodage à utiliser sur la connexion, ce qui est généralement l'approche préférée. En PHP:

    • Si vous utilisez la couche d'abstraction PDO avec PHP ≥ 5.3.6, vous pouvez spécifier charset dans le DSN :

      $dbh = new PDO('mysql:charset=utf8mb4');
      
    • Si vous utilisez mysqli , vous pouvez appeler set_charset() :

      $mysqli->set_charset('utf8mb4');       // object oriented style
      mysqli_set_charset($link, 'utf8mb4');  // procedural style
      
    • Si vous êtes bloqué avec mysql mais que vous utilisez PHP ≥ 5.2.3, vous pouvez appeler mysql_set_charset .

  • Si le pilote ne fournit pas son propre mécanisme de définition du jeu de caractères de connexion, vous devrez peut-être émettre une requête pour indiquer à MySQL comment votre application s'attend à ce que les données de la connexion soient encodées: SET NAMES 'utf8mb4' .

  • La même considération concernant utf8mb4 / utf8 s'applique comme ci-dessus.

Sortie :

  • Si votre application transmet du texte à d'autres systèmes, ils devront également être informés de l'encodage des caractères. Avec les applications Web, le navigateur doit être informé du codage dans lequel les données sont envoyées (via les en-têtes de réponse HTTP ou les métadonnées HTML ).

  • En PHP, vous pouvez utiliser l'option php.ini default_charset , ou émettre vous-même l'en-tête MIME Content-Type , ce qui représente plus de travail mais a le même effet.

Entrée :

  • Malheureusement, vous devriez vérifier chaque chaîne reçue comme UTF-8 valide avant d'essayer de la stocker ou de l'utiliser n'importe où. PHP mb_check_encoding() fait l'affaire, mais vous devez l'utiliser religieusement. Il n'y a vraiment aucun moyen de contourner cela, car les clients malveillants peuvent soumettre des données quel que soit l'encodage qu'ils veulent, et je n'ai pas trouvé de truc pour que PHP le fasse pour vous de manière fiable.

  • De ma lecture de la spécification HTML actuelle, les sous-puces suivantes ne sont plus nécessaires ou même plus valides pour le HTML moderne. Ma compréhension est que les navigateurs vont travailler avec et soumettre des données dans le jeu de caractères spécifié pour le document. Toutefois, si vous ciblez des versions plus anciennes de HTML (XHTML, HTML4, etc.), ces points peuvent toujours être utiles:

    • Pour le HTML avant HTML5 uniquement : vous voulez que toutes les données qui vous sont envoyées par les navigateurs soient en UTF-8. Malheureusement, si vous utilisez le seul moyen fiable de le faire, ajoutez l'attribut accept-charset à toutes vos balises <form> : <form ... accept-charset="UTF-8"> .
    • Pour le HTML avant HTML5 uniquement : notez que la spécification HTML du W3C indique que les clients "devraient" par défaut renvoyer des formulaires au serveur quel que soit le jeu de caractères utilisé par le serveur, mais ceci n'est qu'une recommandation, d'où la nécessité d'être explicite. <form> .

Autres considérations de code :

  • De toute évidence, tous les fichiers que vous allez servir (PHP, HTML, JavaScript, etc.) doivent être encodés en UTF-8 valide.

  • Vous devez vous assurer qu'à chaque fois que vous traitez une chaîne UTF-8, vous le faites en toute sécurité. C'est malheureusement la partie difficile. Vous voudrez probablement faire un usage intensif de l'extension mbstring de PHP.

  • Les opérations de chaîne de caractères PHP intégrées ne sont pas sécurisées par défaut par l'UTF-8. Il y a certaines choses que vous pouvez faire en toute sécurité avec les opérations de chaînes PHP normales (comme la concaténation), mais pour la plupart des choses, vous devez utiliser la fonction mbstring équivalente.

  • Pour savoir ce que vous faites (lire: ne pas le gâcher), vous avez vraiment besoin de connaître UTF-8 et comment cela fonctionne au niveau le plus bas possible. Consultez l'un des liens de utf8.com pour de bonnes ressources pour apprendre tout ce que vous devez savoir.





utf-8