jueves, 10 de abril de 2008

Conversión de UNICODE y LATIN1 en PHP 5

La principal innovación de PHP 6 será el soporte nativo a UNICODE, sin embargo aún queda un largo camino.

Algunos módulos de PHP 5 internamente ya operan con UNICODE como es el caso de DOM que está desarrollado sobre libxml2, esta característica brinda un gran potencial pero a la vez da muchos dolores de cabeza ya que hay que hacer convivir datos codificados usualmente en ISO-8859-1 (LATIN1) y UTF-8.

Para poder realizar conversiones de codificación PHP provee de las funciones utf8_encode() y utf8_decode(). Sin embargo, es bastante común equivocarse y convertir a UTF-8 datos que ya están en dicha codificación o cometer el mismo error con datos codificados ISO-8859-1 lo cual nos corrompe algunos caracteres y puede causar errores en documentos XML y WebServices.

Este es un ejemplo de errores típicos de codificación:

En otras ocasiones, cuando hay que procesar datos de entrada (ej: leer archivos), uno no sabe de antemano si los datos a procesar vendrán codificados en UTF-8 o ISO-8859-1, o en un peor escenario podrían recibirse datos en ambas codificaciones.

Para solucionar estos problemas he construido unas funciones que detectan la codificación de un string y de esta manera realizan la conversión de codificación sólo si es necesario. Las funciones la he llamado latin1() que convierte los datos a ISO-8859-1 y utf8() que convierte a UTF-8.

Debido a que utilizan la función mb_detect_encoding(), es necesario que PHP tenga habilitado el módulo mbstring.



Función que converte un string a ISO-8859-1 (LATIN1)
function latin1($txt) {
$encoding = mb_detect_encoding($txt, 'ASCII,UTF-8,ISO-8859-1');
if ($encoding == "UTF-8") {
$txt = utf8_decode($txt);
}
return $txt;
}


Función que converte un string a UTF-8
function utf8($txt) {
$encoding = mb_detect_encoding($txt, 'ASCII,UTF-8,ISO-8859-1');
if ($encoding == "ISO-8859-1") {
$txt = utf8_encode($txt);
}
return $txt;
}

10 comentarios:

Anónimo dijo...

Gracias! un buen aporte y explicación muy facil de los problemas que nos traen con xml los acentos y otros caracteres "malditos"
Un saludo

Anónimo dijo...

Muchas gracias!! Llevo toda la tarde buscando cómo resolver el problema y por fin he dado con una respuesta fácil y sencilla.

Sergio dijo...

Muchas gracias amigo. Renegé un rato largo con este tema. Estoy enviando datos de un formulario con ajax y al hacer el insert/update los acentos y eñes se transformaban en mutantes al ingresar a la DB MySQL. Solucioné haciendo pasar el sql por tu función antes de correr el insert/update para que me transforme en latin1. Excelente, problema resuelto, muchas gracias.

Anónimo dijo...

Excelente!! Una solución sencilla y bien hecha. Me ayudaste mucho, había pérdido mucho tiempo con este tema.

Anónimo dijo...

Muchísimas gracias por la excelente explicación!!!!. No sabes la de vueltas que he dado hasta resolver este problema.

Anónimo dijo...

muchas gracias, este código me funcionó muy bien, pero tengo un problema y es que en windows funciona perfectamente, pero para linux y AIX necesito obtener la librería compilada para éstos sistemas operativos, será que sabes donde puedo obtener esta librería para linux y/o AIX?

Hipnos dijo...

Hola!

Muchas gracias por el código. :)

Anónimo dijo...

Aquí te dejo una versión que auna las dos funciones que has realizado, detectando y codificando:

public function encoding ($txt, $esp = 0) {
$encoding = mb_detect_encoding($txt, 'ASCII,UTF-8,ISO-8859-1');
echo $encoding;
if ($encoding == "ISO-8859-1") {
$txt = utf8_encode($txt);
//$txt = utf8_decode($txt);
}
if ($encoding == "UTF-8") {
$txt = utf8_decode($txt);
}
return $txt;
}

Anónimo dijo...

Muchas gracias! mas claro no se puede... Saludos

Rolando Quintero F dijo...

OMG!!! DEMASIADO RAJADO, LO HE BUSCADO CASI POR 5 HORAS ESTA SOLUCION, MUCHAS GRACIAS!!!! DEMASIADO PODER....