Prenons comme exemple le code suivant :
<?php
header('Content-type: text/html; charset=utf-8');
$txt = 'é è ㊨';
$nb = strlen($txt);
for($i=0; $i<$nb; $i++){
echo ($i+1).' / '.$nb.' : '.substr($txt, $i, 1).'<br />';
}
?>
Nous avons créer une chaine avec 5 caractères UTF-8 et nous affichons les caractères un à un.
Le fichier PHP est enregistré en UTF-8, le content-type est déclaré en tant qu'UTF-8.
Pourtant les fonctions strlen()
et substr()
ne fonctionnent pas comme on pourrait s'y attendre puisque vous obtenez le résultat suivant :
1 / 9 : �
2 / 9 : �
3 / 9 :
4 / 9 : �
5 / 9 : �
6 / 9 :
7 / 9 : �
8 / 9 : �
9 / 9 : �
Strlen
trouve 9 caractères et substr
ne voit rien de cohérent !
Le problème vient du fait que strlen
et substr
compte des octets et pas des caractères. Or en UTF-8 les caractères peuvent être encodés sur plusieurs octets.
La solution : utiliser les fonctions multi-octets
En PHP il existe un ensemble de fonction permettant de gérer les données multi-octets. Fonctions sur les chaînes de caractères multi-octets.
<?php
header('Content-type: text/html; charset=utf-8');
$txt = 'é è ㊨';
$nb = mb_strlen($txt, 'UTF-8');
for($i=0; $i<$nb; $i++){
echo ($i+1).' / '.$nb.' : '.mb_substr($txt, $i, 1, 'UTF-8').'<br />';
}
?>
Vous obtiendrez le résultat suivant :
1 / 5 : é
2 / 5 :
3 / 5 : è
4 / 5 :
5 / 5 : ㊨
Là on est bon !