PHP: Problemas con strlen y UTF8
Streln es una función de PHP para contar caracteres, su funcionamiento es tan simple como poner strlen($cadena); y regresa el total de caracteres de la cadena. Todo esto seria tan simple si no fuera por UTF8 ya que mete caracteres extras y entonces la cuenta ya no queda como deberia de ser.
Por ejemplo, tenemos un texto en UTF-8 que dice: "papá" (sin las comillas), si ejecutamos strlen nos regresa 5, aunque realmente sabemos que tenemos 4 caracteres. Aquí una explicación del porque tomada de la wikipedia:
Se supone que PHP6 ya soluciona este problema! pero mientras tanto ya tenemos una solución fácil de implementar.
Por ejemplo, tenemos un texto en UTF-8 que dice: "papá" (sin las comillas), si ejecutamos strlen nos regresa 5, aunque realmente sabemos que tenemos 4 caracteres. Aquí una explicación del porque tomada de la wikipedia:
Los caracteres más pequeños que 128dec son codificados con un byte sencillo que contiene su valor: este corresponde exactamente a los caracteres de 7 bits de los 128 del ASCII. En los demás casos, se utilizan de 2 a 4 bytes. El bit más significativo de todos los bytes de esta cadena es siempre 1, para prevenir la confusión con los caracteres de 7-bits del ASCII, particularmente los caracteres menores a 32dec, tradicionalmente llamados caracteres de control.
De este modo, los primeros 128 caracteres necesitan un byte. Los siguientes 1920 caracteres necesitan dos bytes para ser codificados. Esto incluye caracteres del Alfabeto Latino con diacríticos, griego, cirílico, cóptico, armenio, hebreo y arábigo. El resto de los caracteres usan tres bytes y caracteres adicionales son codificados con 4 bytes.
Dentro del rango de codificación con tres bytes se encuentran se encuentran el coreano, chino y japonés.
Bueno, esta algo confuso jeje pero en teoria el acento digamos que tiene 2 letras (para entenderlo un poco mejor), ahora bien la solución a todo esto viene siendo utilizar la función strlen_utf8 en lugar de la strlen que viene por default en PHPDe este modo, los primeros 128 caracteres necesitan un byte. Los siguientes 1920 caracteres necesitan dos bytes para ser codificados. Esto incluye caracteres del Alfabeto Latino con diacríticos, griego, cirílico, cóptico, armenio, hebreo y arábigo. El resto de los caracteres usan tres bytes y caracteres adicionales son codificados con 4 bytes.
Dentro del rango de codificación con tres bytes se encuentran se encuentran el coreano, chino y japonés.
function strlen_utf8 ($str)
{
$i = 0;
$count = 0;
$len = strlen ($str);
while ($i < $len)
{
$chr = ord ($str[$i]);
$count++;
$i++;
if ($i >= $len)
break;
if ($chr & 0x80)
{
$chr <<= 1;
while ($chr & 0x80)
{
$i++;
$chr <<= 1;
}
}
}
return $count;
}
{
$i = 0;
$count = 0;
$len = strlen ($str);
while ($i < $len)
{
$chr = ord ($str[$i]);
$count++;
$i++;
if ($i >= $len)
break;
if ($chr & 0x80)
{
$chr <<= 1;
while ($chr & 0x80)
{
$i++;
$chr <<= 1;
}
}
}
return $count;
}
Trackback URI: http://oviedos.com.mx/index.php/trackback/394

