traducir - ¿La forma más eficiente de hacer archivo de idioma en PHP?
html en español (8)
¿Por qué no lo haces como una matriz multidimensional ... como esta?
<?php
$lang = array(
''EN''=> array(
''NO_PHOTO''=>''No photo/'s avaiable'',
''NEW_MEMBER''=>''This user is new'',
),
''MY''=> array(
''NO_PHOTO''=>''Tiada gambar'',
''NEW_MEMBER''=>''Ini adalah pengguna baru'',
)
);
?>
Preguntas actualizadas en lugar de hacer una nueva pregunta ...
Realmente quiero proporcionar algunos idiomas alternativos además del inglés en mi red social que estoy construyendo, esta será la primera vez que hago cualquier tipo de traducción de idiomas, así que tenga paciencia.
Estoy investigando, así que estoy al oído y abierto a las ideas, y tengo muchas preguntas. Estas son las preguntas.
1)
¿Qué significa i18n, lo veo a menudo cuando busco la traducción de idiomas en SO?
2)
La mayoría de la gente dice que use gettext PHP tiene una extensión o soporte para él,
Bueno, lo he estado investigando y tengo una comprensión básica de ello, por lo que puedo decir, es mucho trabajo adicional para recorrer esta ruta,
Me refiero a codificar mi sitio para usar sus funciones, es decir; _ (''hola mundo estoy en inglés por ahora'') o bien gettext (''hola mundo estoy en inglés por ahora'') no es un problema, ya que cualquier ruta que vaya a tomar requerirá eso.
Pero luego tienes que instalar gettext en tu servidor y hacerlo funcionar,
luego use algunos editores especiales para crear archivos especiales y compilarlos, creo?
Suena como un dolor, entiendo que se supone que esta es la mejor ruta a seguir, bueno, todo el mundo parece decir que lo es.
Entonces, ¿alguien puede decirme por qué esta es la ruta a seguir?
3)
Realmente me gusta la simplicidad de este enfoque, solo construyendo una matriz de idiomas y llamando la frase que necesita en una función como la del ejemplo a continuación, simplemente incluiría un archivo con la matriz de idiomas adecuada.
Lo que realmente quiero saber es si este sería el método de mejor rendimiento en un sitio con mucho tráfico y bastante grande en comparación con el uso de gettext. Si es así, ¿puede explicar por qué?
<?PHP
//Have seperate language files for each language I add, this would be english file
function lang($phrase){
static $lang = array(
''NO_PHOTO'' => ''No photo/'s available'',
''NEW_MEMBER'' => ''This user is new''
);
return $lang[$phrase];
}
//Then in application where there is text from the site and not from users I would do something like this
echo lang(''NO_PHOTO''); // No photo''s available would show here
?>
* Algún código usado de la respuesta de brianreavis a continuación.
Como las otras respuestas no responden realmente a todas las preguntas, buscaré eso en mi respuesta y ofreceré una alternativa sensata.
1) I18n es la abreviatura de Internacionalización y tiene algunas similitudes con I-dieciocho-n.
2) En mi opinión honesta, gettext es una pérdida de tiempo.
3) Tu enfoque se ve bien. Lo que debes buscar son variables de lenguaje. El WoltLab Community Framework 2.0 implementa un sistema de lenguaje bidireccional. Por una vez, hay variables de idioma que se guardan en la base de datos y dentro de una plantilla solo se usa el nombre de la variable que luego se reemplazará con el contenido de la variable en el idioma actual (si está disponible). La segunda parte del sistema proporciona una manera de guardar el contenido generado por el usuario en múltiples idiomas (se requiere entrada en múltiples idiomas).
Básicamente, tiene el texto de la interfaz definido por el desarrollador y el contenido definido por el usuario. El texto multilingüe del contenido se guarda en las variables de idioma y el nombre de la variable de idioma se usa como valor para el campo de texto en la tabla de contenido específico (ya que también es posible el contenido en un solo idioma).
Lamentablemente, la estructura de WCF es muy difícil reutilizar el código fuera del marco, pero puedes usarlo como inspiración. El alcance del sistema depende únicamente de lo que desea lograr con su sitio. Si va a ser grande, definitivamente debería echar un vistazo al sistema WCF. Si es pequeño, bastarán unos pocos archivos de idioma dedicados (de.php, en.php, etc.), desde los cuales se incluye el correcto para el idioma actual.
Desafortunadamente, gettext no funciona bien y tiene problemas en diversas situaciones, como en diferentes sistemas operativos (Windows o Linux) y hacer que funcione es muy difícil.
Además, requiere que configure muchas variables de entorno y dominios y esto no tiene ningún sentido.
Si un desarrollador desea simplemente obtener la traducción de un texto, solo debe establecer la ruta del archivo .mo y obtener la traducción con una función como traducir ("hola", "en_EN"); Con gettext esto no es posible.
Esto podría funcionar mejor:
function _L($phrase){
static $_L = array(
''NO_PHOTO'' => ''No photo/'s available'',
''NEW_MEMBER'' => ''This user is new''
);
return (!array_key_exists($phrase,$_L)) ? $phrase : $_L[$phrase];
}
Eso es lo que uso por ahora. Si no se encuentra el idioma, devolverá la frase, en lugar de un error.
Debe tener en cuenta que una matriz no puede contener más de ~ 65500 elementos. Debería ser suficiente pero bueno, solo decirlo.
Aquí hay un código que uso para verificar el idioma del usuario:
<?php
function setSessionLanguageToDefault() {
$ip=$_SERVER[''REMOTE_ADDR''];
$url=''http://api.hostip.info/get_html.php?ip=''.$ip;
$data=file_get_contents($url);
$s=explode ('':'',$data);
$s2=explode(''('',$s[1]);
$country=str_replace('')'','''',substr($s2[1], 0, 3));
if ($country==''us'') {
$country=''en'';
}
$country=strtolower(ereg_replace("[^A-Za-z0-9]", "", $country ));
$_SESSION["_LANGUAGE"]=$country;
}
if (!isset($_SESSION["_LANGUAGE"])) {
setSessionLanguageToDefault();
}
if (file_exists(APP_DIR.''/language/''.$_SESSION["_LANGUAGE"].''.php'')) {
include(APP_DIR.''/language/''.$_SESSION["_LANGUAGE"].''.php'');
} else {
include(APP_DIR.''/language/''.DEFAULT_LANG.''.php'');
}
?>
Aún no está hecho, pero bueno, creo que esto podría ayudar mucho.
No reinventes la rueda. Utilice, por ejemplo, gettext o Zend_Translate .
Probablemente sería mejor definir una función que maneje su asignación de idioma. De esa manera, si desea cambiar la forma en que funciona más tarde, no se verá obligado a rastrear cientos de scripts para los casos en los que usó $lang[...]
y reemplazarlos con otra cosa.
Algo como esto funcionaría y sería bueno y rápido:
function lang($phrase){
static $lang = array(
''NO_PHOTO'' => ''No photo/'s available'',
''NEW_MEMBER'' => ''This user is new''
);
return $lang[$phrase];
}
Asegúrese de que la matriz se declare static
dentro de la función para que no se reasigne cada vez que se llama a la función. Esto es especialmente importante cuando $lang
es realmente grande.
Para usarlo:
echo lang(''NO_PHOTO'');
Para manejar múltiples idiomas, solo tenga esta función definida en múltiples archivos (como en.php
, fr.php
, etc.) y require()
el apropiado para el usuario.
Puedes hacerlo:
class T {
const language = "English";
const home = "Home";
const blog = "Blog";
const forum = "Forum";
const contact = "Support";
}
Tendrías un archivo como este para cada idioma. Para utilizar el texto:
There is no place like <?=T::home?>.
El inconveniente es que si agrega una nueva constante, debe hacerlo para cada archivo de lenguaje . Si olvidas una, tu página salta para ese idioma. Eso es un poco desagradable, pero es eficiente ya que no necesita crear una matriz asociativa grande y posiblemente los valores incluso se inserten.
Tal vez el acceso podría mejorarse, por ejemplo:
class T {
const home = "home";
public static function _ ($name) {
$value = @constant("self::$name");
return $value ? $value : $name;
}
// Or maybe through an instance:
public function __get ($name) {
$value = @constant("self::$name");
return $value ? $value : $name;
}
}
echo "There is no " . T::_("place") . " like " . T::_("home");
$T = new T();
echo "There is no " . $T->place . " like " . $T->home;
Todavía evitamos la matriz y confiamos en la constant para hacer la búsqueda, lo que supongo que es más costoso que usar las constantes directamente. El lado positivo es que la búsqueda puede usar un respaldo cuando no se encuentra la clave.