Image de l'article Substr, strlen et UTF-8

Substr, strlen et UTF-8

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 !

 

Image Viewer