
De manière interne, PHP gère les chaînes de caractères en ISO-8859-1 et il existe 2 fonctions, (utf8_encode() et utf8_decode(), afin de convertir ces chaînes vers et depuis UTF-8.
Les 128 premiers caractères sont identiques dans les 2 jeux de caractères. Ce sont les caractères ASCII 7, encodés sur 7 bits.
Au-delà, le codage UTF-8 comporte de 2 à 4 octets.
Voici la représentation au niveau du bit des caractères codés en UTF-8:
1 7 0bbbbbbb 2 11 110bbbbb 10bbbbbb 3 16 1110bbbb 10bbbbbb 10bbbbbb 4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
Chaque b représente un bit qui peut être utilisé pour enregistrer un caractère.
On voit que lorsqu'un caractère est codé sur plusieurs octets, tous ces octets sont compris entre les caractères 128 et 255. On peut donc sans aucun danger effectuer, par exemple, un trim sur une chaîne de caractère codée en UTF-8, à condition d'utiliser le trim générique (sans deuxième paramètre), aucun caractère retiré n'étant compris entre 128 et 255.
Voici un petit code qui montre que
<?php
for ($i=128; $i <= 255; $i++) {
$a = chr($i);
$u = utf8_encode($a);
$l = strlen($u);
$o1 = substr($u,0,1);
$o2 = substr($u,1,1);
$v1 = ord($o1);
$v2 = ord($o2);
if ($i < 192) $test = chr(194).chr($i); else $test = chr(195).chr($i-64);
if ($test != $u) echo 'attention';
echo "$i - $a - $u -- $l -- $01 -- $02 -- $v1 -- $v2<br>";
}
?>
Le caractère EUR (euro):
htmlspecialchars() est sûre, les caractères remplacés étant tous des caractères ASCII 7.
Mais htmlentities() transforme, par exemple, les « é » en « é ». htmlentitydecode() est aussi très dangereuse.
trim(), rtrim() et ltrim(), utilisés sans deuxième paramètre, sont sures, les caractères espaces étant tous des caractères ASCII 7.
Il n'y a aucun danger avec la concaténation.
Des fonctions comme strpos(), strlen(), strspn(), strcspn(), retournent leur résultat en octets et non en caractères, ce qui n'est peut être pas ce que vous souhaitez.
substr() ou substr_replace(), utilisés en conjonction avec une fonction comme strpos(), peuvent être sûres. En particulier, Il n'y a aucun danger à couper des chaînes aux espaces ou aux retours à la ligne.
Toutes les fonctions convertissant des majuscules/minuscules, comme strtolower(), strtoupper(), stristr(), strcasecmp(), peuvent corrompre une chaîne UTF-8.
str_split() peut corrompre une chaîne UTF-8 car elle découpe une chaîne à une longueur donnée en octets.
strrev() est aussi une fonction très dangereuse.