Problemas de PHP/Gettext
locale zend-translate (2)
Recuerdo haber realizado algunas pruebas hace unos meses con gettext y el siguiente código funcionó perfectamente:
putenv(''LANG=l33t'');
putenv(''LANGUAGE=l33t'');
putenv(''LC_MESSAGES=l33t'');
if (defined(''LC_MESSAGES'')) // available if PHP was compiled with libintl
{
setlocale(LC_MESSAGES, ''l33t'');
}
else
{
setlocale(LC_ALL, ''l33t'');
}
bindtextdomain(''default'', ''./locale''); // ./locale/l33t/LC_MESSAGES/default.mo
bind_textdomain_codeset(''default'', ''UTF-8'');
textdomain(''default'');
echo _(''Hello World!''); // h3110 w0r1d!
Esto funcionó perfectamente (bajo Windows XP y CentOS si recuerdo correctamente), lo cual fue bueno porque podía usar "locales" arbitrarios , sin tener que preocuparme si estaban instalados en el sistema o no. Sin embargo, esto parece no funcionar más, me pregunto por qué ...
Red Hat + PHP 5.2.11:
Soy capaz de alternar entre diferentes configuraciones regionales y las traducciones se muestran correctamente siempre que la llamada a setlocale()
no devuelva false (si la configuración regional está disponible / instalada en el sistema).
Esto no es perfecto (sería genial si pudiera señalar gettext a cualquier directorio de traducción arbitrario sin tener que probar la existencia de la configuración regional), pero es aceptable. Voy a hacer algunas pruebas más más adelante.
Windows 7 + PHP 5.3.1 (XAMPP):
setlocale()
siempre devuelve falso (incluso cuando se usa LC_ALL
lugar de LC_MESSAGES
), a menos que use alguna configuración regional válida de Windows como eng
, deu
o ptg
; en este caso, la configuración regional parece estar configurada correctamente pero las traducciones aún no aparecen . No puedo probar ahora porque tengo cientos de pestañas abiertas, pero creo que la primera llamada a ese script produce la traducción correcta (reiniciar Apache no funcionará).
No estoy seguro de si esto está relacionado con el error de PHP # 49349 . Voy a probar esto es un par de horas.
¿Hay alguna forma de usar la extensión gettext (que no sea implementaciones PHP puras como php-gettext o el adaptador Zend Translate ) de manera confiable en diferentes sistemas operativos (posiblemente con entornos locales personalizados como l33t
)?
Además, ¿es absolutamente necesario usar setlocale(LC_ALL, ...)
? Preferiría dejar intactas las configuraciones de TIME
, NUMERIC
y MONETARY
(especialmente) (por defecto a POSIX
).
Tenía una idea ... ¿Sería posible llamar a setlocale()
con una configuración regional muy común (como C
, POSIX
o en_US
) y especificar el idioma a través del dominio? Algo como esto:
/lang/C/LC_MESSAGES/domain.pt.mo
/lang/C/LC_MESSAGES/domain.de.mo
/lang/C/LC_MESSAGES/domain.en.mo
/lang/C/LC_MESSAGES/domain2.pt.mo
/lang/C/LC_MESSAGES/domain2.de.mo
/lang/C/LC_MESSAGES/domain2.en.mo
¿Funcionaría sin problemas en las plataformas * nix y Windows?
Este código no se ejecutará perfectamente en todos los sistemas, ya que cada repositorio de configuración regional de sistemas + versión php es diferente, entre otras cosas.
Si desea coherencia, debe usar algo como Zend_Translate, que si instala Zend en cada sistema (la misma versión) todos serían coherentes entre sí porque usan los mismos datos de localización, nombres de configuración regional y base de código.
Hay numerosos errores con setlocale
, simplemente no es confiable. Vea los comentarios en http://php.net/manual/en/function.setlocale.php
Gettext no es demasiado práctico para aplicaciones web.
- Como por ejemplo, no respeta / usa las preferencias de estilo Accept-Language por sí misma.
- Por lo general, incurre en algunos problemas de almacenamiento en caché en hosts web compartidos (mod_php SAPI).
Así que a veces me gustaría que el módulo PHP no existiera, y el conveniente acceso directo al nombre de la función _()
estaba disponible para las implementaciones de los usuarios.
(Tenía mi propio gettext.php , que funcionó más confiable.)
Sus opciones:
De todos modos, de acuerdo con algunos informes de errores, el puerto de Windows de gettext tuvo algunos fallos con UTF-8. Tal vez tu versión se vea afectada de nuevo. Entonces intente
bind_textdomain_codeset(''default'', ''ISO-8859-1'');
para principiantes. Además, parece preferir las variables de entorno en Windows IIRC, así queputenv("LC_ALL", "fr_FR");
podría funcionar mejor quesetlocale()
. Especialmente viable si dl (gettext.dll) más adelante.También dale una oportunidad con la inclusión de un
LANG=en_GB.ISO-8859-1
caracteres allí mismoLANG=en_GB.ISO-8859-1
. (Ya que su texto de origen es inglés de todos modos, preocuparse por el conjunto de caracteres no es muy relevante aquí, pero probablemente sea un caso común en el que Gettext se dispara sobre sí mismo). Ah, y en ocasiones es UTF8, no UTF-8; prueba también ASCII.Alternativamente, evite gettext. Su idea de dominio está cerca, pero simplemente usaría un subdirectorio ./locale/ predefinido para los idiomas:
./lang/en/locale/C/LC_MESSAGES/domain.mo
Luego simplemente invoque
bindtextdomain("default", "./lang/{$APP_LANG}/locale")
sin dar espacio a gettext para que interprete mucho. Siempre buscará / C /, pero ya se ha inyectado el directorio de configuración regional correcto. Pero intente tener un enlace simbólico desde $ LANG a / C / allí de todos modos.Morder en el ñu. Renunciar a gettext. "PhpWiki" tenía un script de conversión awk personalizado. Transforma los archivos .po en scripts de arreglos .php (sí, muy antiguo), y en su lugar solo utiliza una función __ (). Cerrar. Y más fiable.