una - Programación de aplicaciones PHP en varios idiomas
declarar idioma php (10)
Es posible que desee ver un marco como CakePHP o CodeIgniter que hace que escribir aplicaciones internacionalizadas sea mucho más fácil. No se trata de cadenas de caracteres que debe tener en cuenta, sino que también deben tenerse en cuenta los formatos de número y fecha.
Estoy desarrollando una aplicación PHP y me pregunto cuál es la mejor manera de incluir soporte multilingüe para usuarios de otros países.
Soy competente en PHP pero nunca he desarrollado nada con soporte para otros idiomas.
Estaba pensando en poner el lenguaje en un archivo PHP con constantes, por ejemplo:
en.php podría contener:
define(''HZ_DB_CONN_ERR'', ''There was an error connecting to the database.'');
y fr.php podría contener:
define(''HZ_DB_CONN_ERR'', ''whatever the french is for the above...'');
Podría llamar a una función y automáticamente pasar el idioma correcto.
hz_die(''HZ_DB_CONN_ERR'', $this);
¿Es esta una buena manera de hacerlo?
- morristhebear.
Puede usar gettext o algo que admita gettext y más, como Zend_Translate .
Editar:
Solo por precisión, Zend_Translate admite gettext sin el módulo gettext. Aquí puede ver los diferentes tipos de entradas que admite .
Si usa matrices como también se sugiere, también puede usar esto con Zend_Translate. El punto es que si usa matrices hoy y gettext, xml u otra cosa mañana, solo tiene que cambiar su configuración para Zend_Translate.
Su enfoque es viable, en el caso de que incluya diferentes archivos constantes según el idioma elegido por el usuario.
También puede omitir la parte constante y simplemente definir una gran tabla hash con constante => traducción para evitar bloqueos en el espacio de nombres.
archivo: en.php
$constants = Array( ''CONSTANT_KEY'' => ''Translated string'' );
archivo: functions.php
function getConstant($key, $fallback) { // ... return constant or fallback here. }
Sin embargo, cuando se trata de una gran cantidad de datos, este enfoque será difícil de mantener. Hay algunos otros enfoques que podrían servirle mejor a su propósito, por ejemplo, una solución ideal es donde todas sus constantes se almacenan en un espacio de memoria global para todo su sitio, para evitar tener todas y cada una de las entradas / hilos manteniendo todos estos datos traducidos en memoria. Esto requiere algún tipo de enfoque de módulo php. Gettext como alguien aquí sugirió podría usar ese enfoque.
Localización de Google para PHP para encontrar recursos útiles.
Su solución debería funcionar bien siempre que esté destinada únicamente a la traducción. Como han mencionado otros, hay muchas otras variables basadas en la configuración regional, como los formatos de moneda y fecha.
Un enfoque sólido para hacer que su aplicación sea a prueba de Zend_Locale
sería usar Zend_Locale
combinado con Zend_Translate
.
Zend_Locale
te permite detectar fácilmente la configuración regional del usuario o configurarla si lo deseas. Esta clase es útil para establecer automáticamente el formato de moneda correcto, por ejemplo.
Zend_Translate
permite traducir fácilmente texto utilizando varios formatos diferentes:
- Formación
- CSV
- Gettext
- Ini
- Tbx
- Tmx
- Qt
- Xliff
- XmlTm
Un consejo para usted es crear una función que devuelva la cadena traducida, y si no está en la tabla hash, luego devuelva la clave hash que solicitó con un * detrás de ella para notificarle que necesita una traducción.
Extraño. La gente parece estar ignorando la solución obvia. Su idea de los archivos específicos de la configuración regional está bien. Tener en.php:
define(''LOGIN_INCORRECT'',''Your login details are incorrect.'');
...
Entonces, suponiendo que tiene un archivo global de configuración / constantes (que sugeriría por muchos motivos), tenga un código como este:
if ($language == ''en'') {
reqire_once ''en.php'';
} else if ($language == ''de'') {
require_once ''de.php'';
}
Puede definir funciones para visualización de números y monedas, comparación / clasificación (es decir, alemán, francés e inglés tienen diferentes métodos de intercalación), etc.
La gente a menudo olvida que PHP es un lenguaje dinámico así que cosas como esta:
if ($language == ''en'') {
function cmp($a, $b) { ... }
} else if ($language == ''de'') {
function cmp($a, $b) { ... }
}
de hecho son perfectamente legales. Usalos, usalos a ellos.
Así es como lo hago:
parent_script.php:
$lang_pick = "EN"; //use your own method to set language choice
require_once(''trans_index.php'');
echo $txt[''hello''];
trans_index.php:
$text = array();
$text[''hello''] = array (
"EN"=> "Hello",
"FR"=> "Bonjour",
"DE"=> "Guten Tag",
"IT"=> "Ciao"
); //as many as needed
foreach($text as $key => $val) {
$txt[$key] = $text[$key][$lang_pick];
}
Eso puede ser demasiado simple para sus necesidades, pero me parece muy viable. También hace que sea muy fácil mantener las múltiples versiones del texto.
Realmente amo el siguiente enfoque:
un archivo es el traductor mismo:
class Translator{
private static $strs = array();
private static $currlang = ''en'';
public static function loadTranslation($lang, $strs){
if (empty(self::$strs[$lang]))
self::$strs[$lang] = array();
self::$strs[$lang] = array_merge(self::$strs[$lang], $strs);
}
public static function setDefaultLang($lang){
self::$currlang = $lang;
}
public static function translate($key, $lang=""){
if ($lang == "") $lang = self::$currlang;
$str = self::$strs[$lang][$key];
if (empty($str)){
$str = "$lang.$key";
}
return $str;
}
public static function freeUnused(){
foreach(self::$strs as $lang => $data){
if ($lang != self::$currlang){
$lstr = self::$strs[$lang][''langname''];
self::$strs[$lang] = array();
self::$strs[$lang][''langname''] = $lstr;
}
}
}
public static function getLangList(){
$list = array();
foreach(self::$strs as $lang => $data){
$h[''name''] = $lang;
$h[''desc''] = self::$strs[$lang][''langname''];
$h[''current''] = $lang == self::$currlang;
$list[] = $h;
}
return $list;
}
public static function &getAllStrings($lang){
return self::$strs[$lang];
}
}
function generateTemplateStrings($arr){
$trans = array();
foreach($arr as $totrans){
$trans[$totrans] = Translator::translate($totrans);
}
return $trans;
}
los archivos de idioma pueden ser simplemente include()
d y se ven así:
en.php:
Translator::loadTranslation(''en'', array(
''textfield_1'' => ''This is some Textfield'',
''another_textfield '' => ''This is a longer Text showing how this is used'',
));
de.php:
Translator::loadTranslation(''de'', array(
''textfield_1'' => ''Dies ist ein Textfeld'',
''another_textfield '' => ''Dies ist ein längerer Text, welcher aufzeigt, wie das hier funktioniert.'',
));
en tu aplicación puedes traducir una cadena como esta:
$string = Translator::translate(''textfield_1'')
o incluso un montón de cadenas:
$strings = generateTemplateStrings(array(''textfield_1'', ''another_textfield''));
Debido a que los archivos de idioma solo pueden incluirse, puede apilarlos muy fácilmente y, por ejemplo, incluir primero un archivo global y luego incluir archivos de submódulos que pueden agregar nuevas cadenas o reemplazar las ya definidas (lo que no funciona con el define()
-method).
Debido a que es PHP puro, incluso se puede almacenar en caché de código de operación con mucha facilidad.
Incluso tengo scripts alrededor de los cuales se generan archivos CSV que contienen cadenas no traducidas de un archivo y aún mejor: convierte el archivo CSV traducido al archivo de idioma.
Tengo esta solución en uso productivo desde 2004 y estoy muy feliz con esto.
Por supuesto, incluso puede extenderlo con convenciones para pluralizar, por ejemplo. Sin embargo, la localización de formatos de números es algo que tendrías que hacer por otros medios: la extensión intl viene a la mente.
Gracias a todas las personas por sus enfoques y soluciones. Vine aquí con la misma duda inicial, y puedo conluir, que usar el "método de definición" es más realista, ya que, incluso con el extraño problema que no utiliza métodos muy elegantes con otras bibliotecas o algunas, ser realista y en un pensamiento productivo, es tan fácil de mantener y comprender, por lo tanto, puede obtener otros idiomas a través de habilidades no programadas.
Considero mejor que el método de matrices, ya que no necesita distribuir ese gran multilenguaje para obtener algunas traducciones, además, está utilizando menos memoria ya que solo está cargando las cadenas traducidas necesarias.
Sobre la cosa que, esos no pueden ser redefinidos; Bueno, en general, si está definiendo constantes es porque no necesita o no debe cambiarse, por lo tanto, si es necesario, puede usar una sección para cadenas definidas y variables.
Añado que no me gusta cómo se ven los archivos definidos, pero tenga en cuenta que a sus visitantes no les preocupa en absoluto la forma en que se implementa la expresión idiomática, que es una implementación válida y perfecta y que puede obtener fácilmente algunas traducciones.
Puedes usar mi idioma favorito PHP Multi Language Class - LangQuery
Es el más fácil que he visto.
Puede guardar sus datos de idioma en archivos .ini que simplemente llamarlo por
include("LangQuery.php");
$L=new LangQuery();
// Write Hello World
echo($L(''hello_world''));
// Write Hello World Easier - In-line Echo Feature
// You don''t have to write echo. Just add ''>''
$L(''>hello_world'');
// Use in Strings
echo("Hello Universe. {$L(''hello_world'')} Hello Europe");
// Write my age with parameter
$L(">my_age",25);
// Write my name and age with parameters
$L(">my_name_age","Recep",25);