Trabajando con tildes y eñes, con PHP y MySQL, sin morir en el intento.

Database

Si has llegado a este articulo es por que seguramente, en algún momento de tu vida de hiciste la pregunta ¿por que no aparecen las tildes y eñes en mi web?

La respuesta es bastante simple: incompatibilidad de caracteres, pero ¿como podemos asegurar nuestro código sea compatible?

Hace poco tuve una experiencia que me hizo perder mucho, trataba de consultar dos tablas en MySQL pero tardaba mucho la consulta, a pesar de optimizar los indices, llaves foráneas, etc. la consulta tardaba mucho. Indagando en la estructura de datos note que estos tenían un cotejamiento diferente de datos e inmediatamente asumí era mi problema, y vaya que no estaba equivocado.

Con esta introducción presento hacer notar la importancia de manejar una compatibilidad en la codificación de caracteres que utilices. Yo, hasta ahora, siempre he usado UTF-8. ¿Por que usar UTF-8? Simplemente por que es un juego de caracteres muy extenso que tiene caracteres del idioma ingles, español y otros más.

¿Que hacer a nivel de mi código?

A nivel de código HTML utiliza siempre la siguiente etiqueta entro de <head></head>:

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

A nivel de PHP usa siempre la siguiente etiqueta al inicio de tu código:

header("Content-Type: text/html;charset=utf-8");

¿Que hacer a nivel de MySQL?

Es necesario explicar que muchos sitios refieren setear UTF-8 en MySQL por medio de una Query inicial, pero esto no afecta a los métodos de escape, generando muchos dolores de cabeza sin luego comprender donde esta el problema. Para mayor información sugiero leer la guía oficial de PHP sobre este particular, que lo explica bastante bien.

MySQL también debe hablar en UTF-8, para ellos coloco los siguientes ejemplos que debes ejecutar en cada consulta:

mysql_set_charset('utf8', $conexión);

Para MySQLi usarías algo como:

$mysqli->set_charset('utf8');

Y para PDO debes usar algo como (a partir de PHP 5.3.6):

$pdo = new PDO("mysql:host=localhost;dbname=world;charset=utf8", 'mi_usuario', 'mi_contraseña');

 

A nivel de las bases de datos la sugerencia para mantener una mayor compatibilidad es que tengas tus campos con cotejamiento utf8_spanish_ci y que el cotejamiento de tus tablas sea utf_unicode_ci. Esto es lo que generalmente uso y me va muy bien.

¿Que hacer a nivel de Apache?

Personalmente siempre seteo en Apache la codificación de caracteres que uso para archivos .php y .html, para ello uso el siguiente codigo en mi .htaccess:

AddCharset UTF-8 .php

Para entender más sobre apache y la directiva AddCharset, sugiero revisar la guia de W3.org que esta bastante completa y bien explicada.

¿Que hacer a nivel de mis archivos?

Con lo anterior, ya todo debería funcionar, pero existen casos que incrustamos código html con un include de PHP por ejemplo, y este ya no nos muestra las tildes. Esto se debe a que los archivos de nuestro código también debe estar en UTF-8, es un error muy común que veo en foros y comunidades, donde generalmente recurren a «satanizar» datos, cuando lo necesario es cambiar la codificación de nuestros archivos.

Con el siguiente comando de linux, puedes saber la codificación de un fichero:

file -i archivo.php

Lo que retornaría algo como:

archivo.php: text/x-php; charset=iso-8859-1

Ahora sabemos con certeza nuestro archivo.php tiene codificación iso-8859-1 y que al incrustarlo en nuestro script que en su cabecera hemos seteado chatset=utf-8, vamos a tener una incompatibilidad de caracteres.

Para cambiar la codificación de caracteres de un archivo en linux, usamos el siguiente comando:

iconv -f ISO-8859-1 -t UTF-8 archivo.php > archivo.php.utf8

Notamos como el comando iconv permite el definir el origen de codificación y a que juego de caracteres deseamos convertirlo. El archivo a generar es archivo.php.utf8, lo podemos revisar que todo este ok y luego siemplemente renombrarlo.

¿Que hacer si, a pechar de haber seguido los pasos anteriores, aun sigo con problema de las tildes y eñes?

Con todo lo indicado anteriormente, no deberías tener problemas, por lo que sugeriría revisar con detenimiento lo explica. Pero si necesitas trabajar con diferente codificaciones de caracteres por A o B razón, sugeriría los siguientes «tips», adicional a lo anterior:

Para PHP:

Decodifica a UTF-8 tus cadenas con la funcion utf8_decode()

$variable = utf8_decode($variable);

Otra opción desesperada es convertir los caracteres aplicables a entidades html con la función htmlentities() y posteriormente reemplezar estos caracteres para satanizar así los datos. Mayor información en la guia oficial de PHP

Para MySQL;

Si tienes tablas en latin1 por ejemplo, y por otras razones no pueden cambiar el cotejamiento, puedes convertir los datos directamente en tus query con el siguiente código de ejemplo:

SELECT convert(cast(convert(campo1 using latin1) as binary) using utf8) AS campo1

 

Espero la guía sea de vuestro agrado y les ayude a solucionar estos problemas que varios dolores de cabeza nos suele traer. ¡Happy coding!