PHP Substr y el problema con los acentos

Si utilizas substr para cortar una string en PHP, resulta que si ésta tiene acentos o la ñ, la función no trabajará bien. PHP y su función Substr te dará problema si la frase contiene acentos o la ñ si no vas con cuidado.

Programación PHP

Cómo funciona Substr

Si visitáis el manual de PHP de la función, veréis que la estructura es:

substr ( string $string , int $start [, int $length ] ) : string

Pongamos un ejemplo para verlo más claro:

$frase= "Hola me llamo Antonio";
$frasecortada= substr($frase, 0, 10);
echo $frasecortada;
// El resultado que se mostrará es:
// Hola me ll

Por parámetros:

  • $string: la frase a cortar
  • $start: en qué posición empezar. En nuestro caso, queremos coger desde la primera posición, por lo tanto el 0.
  • $length: cuántos caracteres queréis coger. En nuestro caso, cogemos 10 caracteres.

El problema de substr con los acentos

¿Dónde está el problema en esta función? Pues en los acentos.

Como trabaja con bytes, cuando son caracteres alfanuméricos normales, éstos ocupan un byte y no hay problema. Pero, los caracteres acentuados, ocupan 2 bytes. Y es aquí donde empieza la odisea.

Veamos el caso extremo para que lo veáis más claro:

$frase= "áéíóúáéíóúáéíóúáéíóú";
$frasecortada= substr($frase, 0, 10);
echo $frasecortada;
// El resultado que esperamos es que nos devuelva
// áéíóúáéíóú
// Pero no, nos devuelve:
// áéíóú

Resulta que como las acentuadas ocupan 2 bytes, nos devuelve la mitad !!! En el caso de de haber caracteres mezclados, acentuados y sin acentuar, nos devolvería quitando tantos bytes como caracteres acentuados hay…

Parece un lío, y lo es. Pero resumiendo, sería que si utilizamos substr con frase que contengan acentos, nos devolveran menos caracteres de los que esperamos, y ésto puede hacer que almacenemos menos información de la que realmente nos añaden en un formulario, por ejemplo.

Cómo lo resolvemos

Por suerte PHP tiene contemplado este problema. Deberemos utilizar la función mb_substr que nos permite indicarle el Charset con el que queremos trabajar:

$frase= "áéíóúáéíóúáéíóúáéíóú";
$frasecortada= mb_substr($frase, 0, 10, "UTF-8");
echo $frasecortada;
// El resultado, ahora sí, es
// áéíóúáéíóú

Pasa lo mismo con la ñ… Así que atentos.

Espero que con este artículo podáis solucionar los posibles errores de PHP Substr y el problema con los acentos


Más información