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:
- Réglez l'encodage interne de PHP sur UTF-8.
- Enregistrez tous vos fichiers source au format UTF-8.
- Utilisez UTF-8 comme encodage de sortie (n'oubliez pas d'envoyer des en-
Content-type
têtes appropriés ).
- Définissez la connexion à la base de données pour utiliser UTF-8 (
SET NAMES UTF8
dans MySQL).
- Configurez tout le reste pour être UTF-8 si possible.
- Pour tout ce que vous ne pouvez pas contrôler (par exemple, les services Web tiers), assurez-vous de connaître l'encodage et convertissez-le en UTF-8 le plus tôt possible, puis revenez à l'autre encodage le plus tard possible.
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 ensuite echo $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:
$original = "शक्नोम्यत्तुम्";
echo strlen($original);
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.