UTF8?
UTF16?
Les chaînes en PHP conservent-elles également l'encodage utilisé?
Regardons ce script par exemple. Dis que je cours:
$original = "शक्नोम्यत्तुम्";
Que se passe-t-il réellement?
Évidemment, je pense $original
qu'il ne contiendra pas seulement 7 caractères. Ces glyphes doivent chacun y être représentés par plusieurs octets.
Alors je fais:
$converted = mb_convert_encoding ($original , "UTF-8");
Que va-t-il arriver $converted
? En quoi sera-t-il $converted
différent de $original
?
Sera-ce exactement la même séquence d'octets, $original
mais avec un codage différent?
Réponses:
Une chaîne PHP n'est qu'une séquence d'octets, sans aucun encodage qui lui soit associé. Les valeurs de chaîne peuvent provenir de diverses sources: le client (via HTTP), une base de données, un fichier ou des littéraux de chaîne dans votre code source. PHP lit tout cela sous forme de séquences d'octets, et il n'extrait jamais aucune information d'encodage.
Tant que toutes vos sources et destinations de données utilisent le même encodage, le pire qui puisse arriver est que les positions des chaînes sont incorrectes (si vous utilisez des encodages multi-octets), car PHP comptera les octets, pas les caractères.
Mais si les encodages ne correspondent pas (par exemple, vous écrivez un littéral de chaîne dans un fichier source stocké en UTF-8, puis l'envoyez à une base de données qui attend Latin-1), PHP n'effectuera aucune conversion pour vous: il le fera heureusement copier les octets sur raw.
La solution la plus saine est la suivante:
Content-type
têtes appropriés ).SET NAMES UTF8
dans MySQL).Pourquoi UTF-8? Parce qu'il peut représenter tous les caractères Unicode et remplace ainsi tous les encodages 7 bits et 8 bits existants, et parce qu'il est compatible binaire avec ASCII, c'est-à-dire que chaque chaîne ASCII valide est également une chaîne UTF-8 valide (mais pas vv .).
Dans votre exemple, ce qui se passe est le suivant.
Tout d'abord, vous enregistrez votre fichier source; votre éditeur de texte est probablement configuré pour utiliser UTF-8, donc votre chaîne littérale finit par être codée UTF-8 sur le disque. PHP lit ce fichier, interprétant la chaîne comme une série d'octets;
$original
contient désormais une chaîne codée en UTF-8 de 7 caractères, qui n'est qu'une séquence d'octets (bien qu'elle contienne plus de 7 octets, car chaque caractère est représenté par deux octets ou plus). Si vous appelez ensuiteecho $original
, la chaîne encodée est envoyée au client en l'état; si vous avez dit au client de s'attendre à UTF-8, tout va bien, mais si ce n'est pas le cas, PHP n'a aucun moyen de faire la différence, et vous vous retrouverez avec des ordures dans le navigateur. À titre expérimental, essayez ceci:strlen
est indépendant du codage et suppose un codage à 8 bits de largeur fixe, c'est-à-dire un octet par caractère, donc il comptera les octets, pas les caractères.la source