2009-08-29 23 views
18

Im un hobbycoder que está tratando de construir su primer sitio MultilangualPHP detección de idioma

utilizo este pedazo de código para detectar el lenguaje usuarios. Si no has elegido un idioma que incluirá el archivo de lenguaje basado en HTTP_ACCEPT_LANGUAGE no sé donde se obtiene de Tho ..

session_start(); 

if (!isset($_SESSION['lang'])) { 
    $_SESSION['lang'] = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); 
} 

elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'en') $_SESSION['lang'] = "en"; 
elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'sv') $_SESSION['lang'] = "sv"; 
elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'pl') $_SESSION['lang'] = "pl"; 
elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'fr') $_SESSION['lang'] = "fr"; 

include('languages/'.$_SESSION['lang'].'.php'); 

Funciona para mí, e incluye el archivo lang esmalte. ¿Pero es este código exacto? ¿¿O hay otra manera?? ¿Cómo crees que YouTube hace esto, por ejemplo?

Sería grandioso si algunos ingleses, franceses, suecos o polacos pudieran visitar mi sitio y ver si incluye el archivo correcto. Así que sé que no funciona para mí :) http://jorm.homeftp.org/

De todos modos, ¿crees que podría mejorar mi código? ¡se verá desordenado a medida que agrego más idiomas con todos los demás!

Gracias

+0

¿Qué pasa si el encabezado es 'Aceptar Idioma: fr; q = 0, en' o algo por el estilo? – eisberg

Respuesta

27

El navegador generalmente envía una cabecera HTTP, el nombre Accept-Language, que indica qué idiomas el usuario está dispuesto a conseguir.

Por ejemplo, esta cabecera puede ser:

Accept-Language: en-us,en;q=0.5 

hay noción de prioridad en la que, por cierto ;-)

En PHP, usted puede conseguir esto en el $_SERVER súper mundial:

var_dump($_SERVER['HTTP_ACCEPT_LANGUAGE']); 

me llevará:

string 'en-us,en;q=0.5' (length=14) 

Ahora, usted tiene que analizar que ;-)


Si puedo editar mis preferencias en la opción del navegador para decir: "Quiero francés, y si no puede servir no me francés, dame Inglés De los Estados Unidos ; y si no me puede conseguir que, o bien, simplemente me Inglés), el encabezado será:

Accept-Language: fr-fr,en-us;q=0.7,en;q=0.3 

Y, desde PHP:

string 'fr-fr,en-us;q=0.7,en;q=0.3' (length=26) 


Para más información, se puede tomar un vistazo a section 14.4 of the HTTP RFC.

Y probablemente pueda encontrar muchos ejemplos de código en PHP para analizar ese encabezado; por ejemplo: Parse Accept-Language to detect a user's language

¡Diviértete!

+0

respuesta impresionante gracias! –

+1

De nada :-) –

+0

Guau, ¡bien! He estado buscando esto ... – simPod

3

Aquí está el script que utilicé para un sitio bilingüe. Se debe utilizar como index.php de mysite.com. Según la preferencia de idioma del navegador del usuario, se redirigiría a la versión de idioma deseada del sitio o del sitio de idioma predeterminado si el sitio en el idioma preferido del usuario no estuviera disponible.

<?php 
// List of available localized versions as 'lang code' => 'url' map 
$sites = array(
    "en" => "http://en.mysite.com/", 
    "bn" => "http://bn.mysite.com/", 
); 

// Get 2 char lang code 
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); 

// Set default language if a `$lang` version of site is not available 
if (!in_array($lang, array_keys($sites))) 
    $lang = 'en'; 

// Finally redirect to desired location 
header('Location: ' . $sites[$lang]); 
?> 
1

Su código se ve bien.Es posible que desee agregar una última opción predeterminada else si el visitante solicita un idioma que no está proporcionando. Además, si el visitante mismo selecciona un idioma, debe guardar esa opción en una cookie persistente y verificar su valor, dándole prioridad sobre HTTP_ACCEPT_LANGUAGE.

Por lo que puedo decir, Youtube utiliza HTTP_ACCEPT_LANGUAGE, pero al mismo tiempo utiliza la geolocalización de IP para sugerir un cambio de idioma si el idioma del país del visitante no coincide con eso. Definitivamente molesto

Sólo nitpicking: si va a agregar idiomas a la lista, una declaración switch() podría ser más legible.

1

Trate Esta

function getUserLanguage() { 
    $langs = array(); 

    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { 
     // break up string into pieces (languages and q factors) 
     preg_match_all(
      '/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', 
      $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
      $lang_parse 
     ); 

     if (count($lang_parse[1])) { 
      // create a list like 'en' => 0.8 
      $langs = array_combine($lang_parse[1], $lang_parse[4]); 

      // set default to 1 for any without q factor 
      foreach ($langs as $lang => $val) { 
       if ($val === '') { 
        $langs[$lang] = 1; 
       } 
      } 
      // sort list based on value 
      arsort($langs, SORT_NUMERIC); 
     } 
    } 
    //extract most important (first) 
    reset($langs); 
    $lang = key($langs); 

    //if complex language simplify it 
    if (stristr($lang, '-')) { 
     list($lang) = explode('-', $lang); 
    } 

    return $lang; 
} 
+0

Esto parece tener un error de tipo/sintaxis en alguna parte. Supongamos que las citas están rotas. – MrTux

+0

He solucionado esto;) – naitsirch

+0

la expresión regular no coincide con langs como sr-latn-rs o es-419. también * el idioma no se respeta. lo he cambiado a /([az\*\-0-9]+)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/iy el segundo argumento de array_combine desde $ lang_parse [4] a $ lang_parse [3] – bhelm

0
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){ 
    $parts=explode(';',$_SERVER['HTTP_ACCEPT_LANGUAGE']); 
    $langs=explode(',',$parts[0]); 
    var_dump($langs); 
} 
+3

¿Podría explicarnos más sobre lo que está pasando? – andy

+0

Utilice este código y obtendrá una matriz de idiomas de aceptación –

+0

Quería señalar que una buena respuesta debe incluir una explicación en lugar de solo soltar el código. – andy

4

que puede utilizar: Locale::acceptFromHttp().

Intenta encontrar una configuración regional que pueda satisfacer la lista de idiomas solicitada por el encabezado HTTP "Aceptar idioma".

+0

tenga en cuenta que esta función solo devuelve los idiomas que considera válidos. Tuve el problema en Egipto de que devuelve en_US para las personas que prefieren AR-AR (que no es una variante de idioma oficial, por supuesto, pero parece que se usa) – bhelm

3

Sé que hay ya muchas buenas soluciones, pero mi es el mejor;)

<?php 
    $prefLocales = array_reduce(
    explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']), 
     function ($res, $el) { 
     list($l, $q) = array_merge(explode(';q=', $el), [1]); 
     $res[$l] = (float) $q; 
     return $res; 
     }, []); 
    arsort($prefLocales); 
    /* 
    This get you from headers like this 
     string 'en-US,en;q=0.8,uk;q=0.6,ru;q=0.4' (length=32) 
    array like this 
    array (size=4) 
     'en-US' => float 1 
     'en' => float 0.8 
     'uk' => float 0.6 
     'ru' => float 0.4 
    */ 
0

esto también es posible. Utilizará inglés como predeterminado si .php no está disponible.

$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); 
(@include_once 'languages/'.$lang.'.php') or (@include_once 'languages/en.php'); 
Cuestiones relacionadas