[PHP & MySQL] Tratar correctamente los acentos y demás

Publicado por Alejandro Escario en

No es la primera ni será la última vez que yo o gente que conozca, tenga problemas con los acentos en aplicaciones web que usen tecnologías PHP y MySQL. Realmente solucionar este problema no es tan complicado y, por ello, vamos a intentar abordar dos soluciones que se pueden usar por separado o unidas según nuestras necesidades.

Pero antes de proponer cada una de las soluciones por separado, vamos a ver un ejemplo de lo que estamos hablando: Supongamos que en nuestra página web hay un campo de entrada de datos, y en ella el usuario escribe:

Café Roma

Acto seguido pulsa el botón «Aceptar» para guardar ese texto en la base de datos. Todo parece ir bien, pero al recuperarlo de la base de datos y mostrarlo por pantalla vemos que escribe algo parecido a lo siguiente:

Café Roma

O, incluso

Caf� Roma

A grosso modo, esto ocurre porque estamos mezclando codificaciones uno o más sitios (navegador del usuario, servidor Apache con PHP instalado y la base de datos MySQL). Esto es un problema muy común y del que, mucha gente pregunta en foros todos los días y, por ello vamos a proponer soluciones para, en un principio mostrarlo en un navegador de forma correcta.

Conversión a caracteres HTML

HTML tiene una serie de caracteres especiales y reservados que tienen una función especial, un claro ejemplo son los caracteres mayor > y menor <, ya que, por ejemplo, estos caracteres se utilizan para delimitar las etiquetas XML en las que está basada la especificación HTML. Por ello, HTML especifica una serie de códigos llamados «Entidades HTML» que nos permiten codificar estos caracteres especiales. Por ello si queremos poner el símbolo <, realmente deberíamos escribir &lt; o bien &#60;. En el primer caso estaríamos indicando ese carácter usando un código alfanumérico y, en el segundo, estamos indicando el valor de dicho carácter en ASCII.

Como hacer esta conversión manualmente no siempre es posible y, en el caso de que si que lo sea, es bastante tedioso escribir usando esos códigos, PHP nos brinda una función que hará el trabajo sucio por nosotros: htmlentities; de manera que con invocar la función:

$str = htmlentities($str);

De manera que ahora en nuestra variable $str en lugar de tener, por ejemplo, «Camión», que podría darnos problemas al guardarlo en una base de datos si el sistema está mal configurado (más adelante veremos como configurarlo bien), tendríamos una variable que contiene «Cami&oacute;n», es decir, un string compuesto únicamente por caracteres ASCII que no debería darnos problema a la hora de persistirlo en cualquier base de datos; tenga el cotejamiento que tenga.

Finalmente, si vamos a mostrar el código por pantalla, tenemos dos opciones:

  1. Si vamos a mostrarlo en una web, no hace falta que tratemos el string para volver al formato original, ya que los navegadores son capaces de interpretar estos «caracteres codificados».
  2. En caso de que no se coloque dentro de un fichero con formato (X)HTML, nos bastará con llamar al método html_entities_decode.

Almacenamiento directo

Lo que hemos visto en el apartado anterior, no deja de ser una chapuza (para la mayor parte de los casos) y que se puede solucionar de una forma bastante sencilla y, es que, si configuramos bien nuestro servidor Apache con PHP, nuestra base de datos MySQL y la conexión entre ambas, podemos ahorrarnos todo este tratamiento de datos; y no solo eso, sino que además, nos permitirá consultar cómodamente los datos almacenados desde cualquier otro sistema sin tener que perocuparnos de deshacer la codificación de caracteres extraños.

Vamos a ver los pasos para realizar esta configuración directamente:

  • El cotejamiento de la tabla (el de la base de datos también debería estarlo), debería de estar configurado en utf8, en mi caso, voy a utilizar utf8_unicode_ci. Esto podemos configurarlo, si usamos phpmyadmin, desde las opciones de la tabla.

  • Apache (con PHP instalado) y MySQL son dos servidores completamente separados y que, no tienen por qué usar el mismo idioma, de hecho, a no ser que tengamos instalado en PHP el conector de MySQL, no seremos capaces de comunicarnos entre ambos servidores. Por ello, es interesante configurar la conexión, en este caso, el idioma en el que van a hablar; para ello, tenemos que decirle a MySQL que queremos todos los campos en UTF-8 ejecutando la siguiente query:
 SET NAMES 'utf8'&amp;nbsp;
  • En caso de querer mostrar los datos en un fichero (X)HTML, deberíamos indicar el cotejamiento de la página añadiendo la siguiente etiqueta <meta> en el header de la página.
&amp;nbsp;&amp;lt;meta http-equiv=&quot;Content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&amp;gt;&amp;nbsp;
Categorías: ManualesPHP

1 comentario

alarmas para el hogar · julio 3, 2013 a las 3:49 pm

[PHP & MySQL] Tratar correctamente los acentos y demás | Dipler, ¿Puedes aportar más?, me resulta insterense esta post. Saludos.

Los comentarios están cerrados.