Desarrollos multilingües en PHP

Al iniciar un desarrollo para una solución en línea vía web es ya casi obligado incluir en el análisis inicial el soporte multilingüe. Las posibilidades para hacerlo son muchas aunque básicamente se centran en dos opciones: traducciones en base de datos o traducciones en el propio código.

Las ventajas de una y otra son varias; en mi caso opto por las traducciones en código porque de esta manera tengo disponible desde el primer momento cualquier mensaje que deba recibir el usuario final en el idioma escogido o establecido, independientemente del estado de la conexión o disponibilidad de la base de datos (casi siempre, MySQL).

Como mostrar el desarrollo completo es largo, resumiré aquí mi howto, aunque las maneras son muchas y dependen del estilo de programación de cada equipo de proyecto. En este caso se trata de una programación mixta estructurada y objeto, muy sencilla de utilizar.


En primer lugar un módulo PHP que contiene una clase llamada idioma cuyo constructor crea una matriz asociativa donde la clave es el texto original en castellano, utilizado como idioma de base, y el valor que contiene es la traducción en el idioma que se desea; algo así, para PHP4:

class idioma {
 var $textos = array();
 function idioma() {
  $this->textos['¡Hola Mundo!'] = 'Hello World!';
 }
}

Además, incluyo una función en la clase idioma que hará la labor de traductor. Su funcionalidad es extremadamente simple. Si hay una posición en la matriz asociativa para la clave dada (una palabra o frase en castellano) entonces devuelve su contenido (traducción), en caso contrario devuelve la propia clave (texto en idioma original).

Su funcionalidad podría complicarse. Por ejemplo, observarás que en mi ejemplo necesitaría dos declaraciones en la matriz para la palabra hola, una que contemple "Hola" y otra para "hola" o incluso una tercera para "HOLA". La función podría complicarse para incluir en la matriz una sola vez la palabra y que esta copiase el formato de la original enviada a la función. No sé si me explico correctamente.

function T($texto) {
 if (isset($this->textos[$texto])) {
  return $this->textos[$texto];
 }
 else {
  return $texto;
 }
}

¿Cómo uso esta clase? Sencillo. He creado tantos módulos como idiomas pretendo que se dispongan en la aplicación a desarrollar. Tendré un en.php, un fr.php, un de.php... y así, los que desee tener.

En el index.php realizo un include o un require para incluir un idioma determinado, inicialmente cargo es.php, que no necesita incluir traducción alguna dado que la función devolverá el parámetro que recibe al no encontrar una posición en la matriz asociativa.

Unos iconos asociados a un enlace pueden recargar la página pasando como parámetro una variable que contenga en, fr, de..., a la vez que compondría el include del módulo de esta manera básica:

if (isset($_REQUEST['lang']) {
 require("idiomas/" . $_REQUEST['lang'] . ".php");
}
else {
 require("idiomas/es.php");
}

Una vez incluido el módulo, inicializo la clase:

$I = new idioma();

A continuación, en los envíos de mensajes a terminal empleo la clase de esta manera:

echo $I->T("¡Hola Mundo!");

Esta es la base. Las mejoras son muchas. Por ejemplo, controlar que exista el archivo PHP del idioma asociado al valor de $_REQUEST['lang'] (en el ejemplo mostrado).

Ahora sólo falta hacer un editor para modificar las traducciones o crear uno nuevo. Para ello necesito que el directorio tenga los permisos adecuados de escritura. En el módulo antes y después de la declaración de la matriz $textos incluyo unas marcas como comentarios.

El módulo de traducción puede leer esa parte (a través de fopen y fgets), evaluar el código mediante eval para crear la matriz, mostrarla a través de una interface al usuario y que éste pueda editar las traducciones o añadir nuevas y, por último, que genere nuevamente el módulo, incluyendo todo lo necesario, utilizando fwrite.

Sé que no soy muy preciso con todo el conjunto porque sería largo y extenso, pero si hay interés, publicaré algún ejemplo completo. Si buscabas algo así, espero que esta guía sea de ayuda para empezar tu propio desarrollo multilingüe.

Comentarios

Entradas populares