Internacionalización PHP (i18n): Guía práctica para desarrolladores

more

Yee

Aug 03, 2024

cover-img

Lleva tu sitio PHP al mundo: una solución de internacionalización más eficiente

Si eres como yo y mantienes proyectos PHP "puros" que no dependen de grandes frameworks (como Laravel o Symfony), el soporte multilenguaje (i18n) seguramente haya sido un pequeño pero persistente dolor de cabeza.

La solución tradicional, gettext, aunque potente, es bastante engorrosa de configurar. Especialmente en proyectos pequeños, se siente como "matar moscas a cañonazos". Lo que realmente necesitamos es un método que se pueda implementar rápido y sin añadir demasiada complejidad.

Después de mucho probar y fallar en varios proyectos, hemos desarrollado una solución ligera de internacionalización basada en archivos de arrays PHP y herramientas de traducción online. Este enfoque no solo es fácil de implementar, sino que además tiene unos costes de mantenimiento bajísimos. Hoy quiero compartir contigo toda esta solución, sin trampa ni cartón.

Guía práctica: Cómo conseguí soporte multilenguaje en PHP con O.Translator

Nuestra idea principal es muy sencilla: Cada idioma corresponde a un archivo PHP, que contiene una sentencia return que devuelve un array asociativo. Este método es simple, intuitivo y apenas afecta al rendimiento.

Paso 1: Planifica la estructura de tus directorios

Tener una estructura de directorios clara es medio camino hecho. Para mantener todo organizado, vamos a poner todos los archivos de idioma en el mismo directorio y los nombraremos usando códigos de idioma, así:

project_root/
├── index.php         // Your main logic file
├── i18n/             // Folder for all language files
│   ├── lang.cn.php   // Chinese language pack
│   ├── lang.en.php   // English language pack
│   └── lang.fr.php   // French language pack

Paso 2: Crea tu "arsenal de idiomas"

Ahora, vamos a crear el archivo base de idioma. Vamos a usar el chino como ejemplo y crear un archivo lang.cn.php. El contenido del archivo es un array PHP sencillo, donde las claves son identificadores únicos y los valores son las cadenas de texto correspondientes.

Ejemplo de lang.cn.php: Las claves se mantienen, los valores cambian según el idioma

Paso 3: Llega el mago de las traducciones, O.Translator

¿Traducir manualmente docenas o cientos de entradas? Ese es el tipo de trabajo repetitivo que más odian los programadores. Aquí es donde entra en juego nuestra arma secreta, O.Translator.

Es una plataforma profesional de traducción de documentos online que soporta perfectamente archivos PHP, permitiéndote leer tu array directamente y traducirlo a más de 70 idiomas.

El proceso es absurdamente sencillo:

  1. Visita la página principal de O.Translator y sube tu archivo de idioma base (por ejemplo, lang.cn.php).
  2. Selecciona los idiomas de destino, como inglés y francés.
  3. Haz clic en traducir, espera un momento y tendrás listos tus archivos traducidos lang.en.php y lang.fr.php.

Lo que más me impresionó es que O.Translator te permite previsualizar una parte de la traducción gratis. Si estás satisfecho con los resultados, entonces puedes decidir si quieres pagar por la traducción completa. En sus propias palabras: "Nunca pagues por un producto con el que no estés satisfecho."

Paso 4: Da vida al código

Todo está listo; solo falta el toque final. Ahora, vamos a modificar el archivo principal index.php para que pueda cargar dinámicamente el paquete de idioma adecuado según la selección del usuario.

<?php

// 1. Determine the current language (using a GET parameter for demonstration)
$supported_langs = ['en', 'cn', 'fr'];
$default_lang = 'en';
$lang = isset($_GET['lang']) && in_array($_GET['lang'], $supported_langs) ? $_GET['lang'] : $default_lang;

// 2. Load the corresponding language file
// Use a global variable like $_ or a specific variable like $TEXTS to store the strings
$_ = require_once __DIR__ . "/i18n/lang.{$lang}.php";

?>

En tu plantilla HTML, puedes llamar fácilmente a las cadenas de texto así:

<!DOCTYPE html>
<html lang="<?php echo htmlspecialchars($lang); ?>">
<head>
    <meta charset="UTF-8">
    <title><?php echo htmlspecialchars($_['heading_home']); ?></title>
</head>
<body>
    <header>
      <h1><?php echo htmlspecialchars($_['heading_home']); ?></h1>
      <nav>
        <ul>
          <li><?php echo htmlspecialchars($_['heading_about']); ?></li>
          <li><?php echo htmlspecialchars($_['button_read_more']); ?></li>
        </ul>
      </nav>
    </header>
</body>
</html>

¡Y ahí lo tienes: así de fácil nace un sitio web multilingüe!

Consideraciones y reflexiones avanzadas

Aunque esta solución es ligera, hay algunos puntos que merece la pena tener en cuenta antes de ponerla en producción:

  • ¿Cómo detectar el idioma del usuario? El ejemplo utiliza un parámetro GET como ?lang=en. En una aplicación real, también podrías usar $_SESSION, $_COOKIE o analizar la cabecera Accept-Language de la petición del navegador para una detección automática.
  • Consideraciones de rendimiento: Para sitios web pequeños o medianos, la sobrecarga de rendimiento de require_once para un archivo PHP en cada petición es insignificante. Si tu sitio tiene mucho tráfico, considera usar tecnologías de caché de bytecode como APC u OPcache para optimizar aún más.
  • Escalabilidad: A medida que aumenta el número de idiomas o cadenas de texto, gestionar los archivos manualmente puede complicarse. En ese momento, quizá debas explorar soluciones i18n más profesionales, como la extensión gettext de PHP o los componentes de localización que ofrecen los frameworks.
  • Consistencia en la traducción: Para garantizar la coherencia de los nombres de marca y la terminología en todas las versiones de idioma, se recomienda encarecidamente utilizar la función de glosario de O.Translator.
  • Estrategia de alto nivel: Este artículo se centra en la implementación técnica. Si quieres saber más sobre la estrategia general para la internacionalización de sitios web, puedes leer nuestro otro artículo en profundidad.

Tema

Escenario

Escenario

Artículos publicados11

Lecturas recomendadas