2009-09-12 9 views
23

Preguntas actualizado en lugar de hacer una nueva pregunta ...¿La forma más eficiente de hacer un archivo de idioma en PHP?

Realmente quiero dar algunos lenguajes alternativos aparte de inglés en mi sitio de red social que estoy construyendo, esta será mi primera vez haciendo cualquier tipo de traducción de idiomas así que por favor tengan paciencia conmigo.
Estoy investigando, así que estoy abierto y abierto a las ideas y ya tengo mucho aquí son las preguntas.

1)
¿Qué significa i18n, lo veo a menudo cuando la investigación de traducción de idiomas en el SO?

2)
La mayoría dice que el uso gettext PHP tiene una extensión o apoyo a la misma,
así he estado investigando y tengo una comprensión básica de la misma, por lo que yo puedo decir que es una gran cantidad de trabajo extra para seguir esta ruta,
Me refiero a la codificación de mi sitio para usar sus funciones; _ ('hola mundo estoy en inglés por ahora') o bien gettext ('hello world estoy en inglés por ahora') no es un problema ya que cualquier ruta que vaya requerirá eso.
Pero luego tienes que instalar gettext en tu servidor y ponerlo en funcionamiento,
y luego usar algunos editores especiales para crear archivos especiales y compilarlos, ¿no?

Suena como un dolor, comprendo que esta se supone que es la mejor ruta, bueno, todos parecen decir que sí.
Entonces, ¿alguien puede decirme por qué este es el camino a seguir?

3)
me gusta mucho la simplicidad de este enfoque, sólo la construcción de una matriz de la lengua y llamando a la frase que usted necesita en una función similar al ejemplo siguiente , A continuación, basta con incluir un archivo con el lenguaje apropiado formación.

Lo que realmente quiero saber es si este sería el método de rendimiento menos eficaz en un sitio de mucho tráfico y bastante grande en comparación con el uso de gettext, y 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 utilizado de la respuesta de brianreavis continuación

+0

Sabe que no tiene que usar _ en una matriz, pero sí, probablemente debería usar las extensiones de php en lugar de hacer las suyas propias. – SeanJA

Respuesta

6

No reinventar la rueda. Use por ejemplo gettext o Zend_Translate.

+8

¡Pero la rueda es cuadrada! – srcspider

+12

-1. ¿Por qué? Debido a que "No reinventar la rueda" es demasiado abusado, para mí la frase significa que en lugar de volver a hacer algo que ya es ideal, úsalo. No, oye, algún tipo hizo una biblioteca que patea el culo, realmente no nos importa que no te guste (demasiado complicado) o lo que sea. – John

+0

El vínculo Zend_Translate está desactualizado, para el uso del marco v1 [este enlace] (http://framework.zend.com/manual/1.12/en/zend.translate.html) & para el marco de trabajo v2 use [este] (http://framework.zend.com/manual/current/en/modules/zend.i18n.translating.html). –

5

No escriba su propio marco idioma. Use gettext. PHP tiene el estándar bindings que puedes instalar.

+0

Acabo de echar un vistazo a la página gettext anterior hoy antes de publicar esto, realmente no puedo entender cómo funciona en pocas palabras, ¿puedes explicar un poco al respecto? – JasonDavis

+0

jasondavis: hace exactamente lo que intentas hacer y más. Cuando lo instala, elige un lugar para colocar su archivo de traducciones de idioma (".po"). Puede traducir todas sus cadenas en este archivo. Luego, en su fuente, ajusta todas sus cadenas multilingües con gettext() (o típicamente un alias, '_()') y extraerá su traducción actual de esa cadena por usted. También proporciona frases en plural y algunas otras características importantes que usted encontrará necesarias. – Fragsworth

+1

@future reader, diré, si su sitio web o aplicación no usa cientos o miles de palabras, ir a la matriz asociativa es mejor que gettext. Gettext está muy desactualizado en sus implementaciones y puede ser una pesadilla para depurar. Acabo de pasar tres días intentando que funcione en mi servidor. Tiene muchos problemas y no está bien mantenido. Confía en mí, te encontrarás con algunos de sus problemas. Mejor sería usar el php-gettext (gettext emulator), algunas otras implementaciones o escribir tu propia biblioteca. –

-1

por qué no acaba de hacerlo lo más matriz multi-dimesional ... como este

<?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', 
    ) 
); 

?> 
+11

Esto utilizaría más memoria de la necesaria --- porque esto sería cargar * cada * idioma para * cada * solicitud. Sería mejor dividirlo en varios archivos y cargar el único apropiado. – brianreavis

18

Probablemente sería mejor para definir una función que se encarga de su asignación de idioma. De esta manera, si desea querer cambiar la forma en que funciona más adelante, no está obligado a buscar cientos de scripts para los casos en los que usó $lang[...] y los reemplazó por otra cosa.

Algo como esto funcionaría y sería bueno & rápida:

function lang($phrase){ 
    static $lang = array(
     'NO_PHOTO' => 'No photo\'s available', 
     'NEW_MEMBER' => 'This user is new' 
    ); 
    return $lang[$phrase]; 
} 

Hacer Seguro la matriz se declara static dentro de la función de modo que no quede reasignado cada vez que la función se llama. Esto es especialmente importante cuando $lang es muy grande.

Para usarlo:

echo lang('NO_PHOTO'); 

Para el manejo de varios idiomas, sólo tienen esta función se define en varios archivos (como en.php, fr.php, etc) y require() el apropiado para el usuario.

+2

FYI, esta solución es inferior a la sugerencia de Fragsworth: 'gettext'. Gettext es definitivamente la mejor ruta para este tipo de cosas. Sin embargo, así es como lo haría si tuviera que implementar su propio sistema básico. – brianreavis

+0

beutifulleeee, ty! – themis

+0

¡Hola, me gusta la solución! Vengo de C# y tengo una duda sobre cómo funcionan las variables estáticas en PHP.Cuando declaras una variable estática en C#, por ejemplo una matriz, esta se guarda en la memoria y solo necesitas cargarla una vez y su valor persiste entre diferentes subprocesos de usuario. Pero en PHP, por lo que sé, pierde el valor en cada ejecución, y si desea mantener las cosas en la memoria, debe usar alternativas como APC. ¿Por qué entonces @brianreavis recomienda que sea estático para no "reasignar" cada vez? ¡Gracias! –

10

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 yo 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 diciendo.

Aquí hay un código que utilizo para comprobar si 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'); 
} 

?> 

No es hecho todavía, pero bueno, creo que esto podría ayudar mucho.

1

Como las otras respuestas realmente no responden a todas las preguntas, iré por eso en mi respuesta más una alternativa sensata.

1) I18n es la abreviatura de Internacionalización y tiene algunas similitudes con I-eighteen-n.

2) En mi opinión honesta gettext es una pérdida de tiempo.

3) Su 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 lenguaje 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 la entrada en múltiples idiomas).

Básicamente tiene el texto de la interfaz que define el desarrollador y el contenido que define el usuario. El texto multilingüe del contenido se guarda en variables de lenguaje y el nombre de la variable de idioma se utiliza como valor para el campo de texto en la tabla de contenido específico (como también son posibles los contenidos de un solo idioma).

La estructura de la WCF es lamentablemente de una manera que reutilizar el código fuera del marco es muy difícil, pero puede usarlo como inspiración. El alcance del sistema depende únicamente de lo que desea lograr con su sitio. Si va a ser grande, definitivamente debe echarle un vistazo al sistema WCF. Si es pequeño, algunos archivos de idiomas dedicados (de.php, en.php, etc.), de los cuales se incluye el correcto para el idioma actual.

+0

* 2) En mi opinión honesta gettext es una pérdida de tiempo. * - ¡De hecho! – almosnow

1

Desafortunadamente gettext no funciona bien y tiene problemas en varias situaciones, como en diferentes sistemas operativos (Windows o Linux) y hacer que funcione es muy difícil.

Además, requiere que configure un montón de variables de entorno y dominios, y esto no tiene ningún sentido.

Si un desarrollador simplemente quiere 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 translate ("hello", "en_EN"); Con gettext esto no es posible.

0

Usted puede hacer esto:

class T { 
const language = "English"; 
const home = "Home"; 
const blog = "Blog"; 
const forum = "Forum"; 
const contact = "Support"; 
} 

usted tendría un archivo como este para cada idioma. Para utilizar el texto:

There is no place like <?=T::home?>. 

La desventaja es que si se agrega una nueva constante, tiene que hacerlo para cada archivo langauge. Si olvida uno, su página se rompe para ese idioma. Eso es un poco desagradable, pero es eficiente, ya que no necesita crear una gran matriz asociativa y, posiblemente, los valores incluso se inline.

Tal vez podría mejorar el acceso, 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 dependemos de constant hacer la búsqueda, que supongo que es más caro que utilizar directamente las constantes. El lado positivo es que la búsqueda puede usar un respaldo cuando no se encuentra la clave.

Cuestiones relacionadas