2009-08-29 27 views
18

Im a hobbycoder, die seiner ersten multilangual Website versuchtPHP Spracherkennung

ich dieses Stück Code verwenden, um zu bauen Benutzer Sprache zu erkennen. Wenn Sie eine Sprache gewählt havent wird der Sprachdatei enthalten, basierend auf HTTP_ACCEPT_LANGUAGE ich weiß nicht, wo sie es von tho bekommt ..

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

Es funktioniert für mich und beinhaltet die Politur lang Datei. Aber ist dieser Code genau? Oder gibt es einen anderen Weg ?? Wie denkst du, dass YouTube das zum Beispiel macht?

Wäre toll, wenn einige Englisch, Französisch, Schwedisch oder Polnisch Leute meine Website besuchen könnten und sehen, ob es die richtige Datei enthält! Also ich weiß, dass es nicht nur für mich funktioniert :) http://jorm.homeftp.org/

Wie auch immer Sie denken, ich könnte meinen Code verbessern? Es wird chaotisch aussehen, da ich mit all diesen anderen Sprachen weitere Sprachen hinzufüge!

Dank

+0

Was ist, wenn die Kopfzeile 'Accept-Language: fr; q = 0, en' oder etwas ähnliches ist? – eisberg

Antwort

27

Der Browser sendet im Allgemeinen einen HTTP-Header, Name Accept-Language, dass der Benutzer, welche Sprachen anzeigt, ist bereit, zu erhalten.

Zum Beispiel kann dieser Header sein:

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

Es gibt Begriff der Priorität darin, btw ;-)

In PHP, können Sie dies in der $_SERVER Super global erhalten:

var_dump($_SERVER['HTTP_ACCEPT_LANGUAGE']); 

wird mich erhalten:

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

Nun müssen Sie analysieren, dass ;-)


Wenn ich meine Vorlieben in der Option Browser bearbeiten zu sagen: „Ich möchte, französisch, und wenn Sie nicht mich nicht französisch dienen, hol mich Englisch aus den USA ; und wenn Sie mir nicht, dass entweder bekommen, nur um mir Englisch), wird der Header sein:

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

Und von PHP:

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


Für weitere Informationen, die Sie ergreifen können ein Blick auf section 14.4 of the HTTP RFC.

Und Sie können wahrscheinlich viele Codebeispiele in PHP finden, um diesen Header zu analysieren; Zum Beispiel: Parse Accept-Language to detect a user's language

Viel Spaß!

+0

ehrfürchtige antwort danke! –

+1

Gern geschehen :-) –

+0

Wow, schön! Ich habe nach diesem gesucht ... – simPod

3

Hier ist das Skript, das ich für eine zweisprachige Website verwendet habe. Es ist als index.php von mysite.com zu verwenden. Basierend auf den Spracheinstellungen des Browsers des Browsers würde es zur gewünschten Sprachversion der Site oder der Standardsprachen-Site umleiten, wenn die Site in der bevorzugten Sprache des Benutzers nicht verfügbar wäre.

<?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

Ihr Code sieht gut aus.Möglicherweise möchten Sie eine endgültige else Standardauswahl hinzufügen, wenn der Besucher nach einer Sprache fragt, die Sie nicht angeben. Wenn der Besucher selbst eine Sprache auswählt, sollten Sie diese Auswahl in einem permanenten Cookie speichern und dessen Wert überprüfen, damit dieser Vorrang vor HTTP_ACCEPT_LANGUAGE erhält.

Soweit ich das beurteilen kann, verwendet Youtube HTTP_ACCEPT_LANGUAGE, verwendet aber gleichzeitig IP Geolocation, um eine Änderung der Sprache vorzuschlagen, wenn die Sprache des Landes des Besuchers nicht mit dieser übereinstimmt. Auf jeden Fall nervig.

Nur pingelig: Wenn Sie Sprachen zu der Liste hinzufügen, könnte eine switch() Anweisung besser lesbar sein.

1

Diese

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

Dies scheint irgendwo einen Syntaxfehler zu haben. Angenommen, die Zitate sind gebrochen. – MrTux

+0

Ich habe das behoben;) – naitsirch

+0

der Regex passt nicht zu Sprachen wie sr-latn-rs oder es-419. Auch * Sprache wird nicht respektiert. Ich habe es geändert in /([az\*\-0-9]+)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i und das zweite Argument von array_combine von $ lang_parse [4] bis $ 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

Können Sie näher erläutern, was hier vor sich geht? – andy

+0

Verwenden Sie diesen Code und Sie erhalten eine Reihe von Sprachen akzeptieren –

+0

Ich wollte darauf hinweisen, dass eine gute Antwort eine Erklärung enthalten sollte, anstatt nur Code löschen. – andy

4

Sie versuchen, verwenden können: Locale::acceptFromHttp().

Versucht, ein Gebietsschema zu finden, das die vom HTTP-Header "Accept-Language" angeforderte Sprachenliste erfüllen kann.

+0

Beachten Sie, dass diese Funktion nur Sprachen zurückgibt, die sie für gültig hält. Ich hatte das Problem in Ägypten, dass es en_US für Leute zurückgibt, die AR-AR bevorzugen (was natürlich keine offizielle Sprachvariante ist, aber anscheinend benutzt wird) – bhelm

3

Ich weiß, dass es bereits viele gute Lösungen, aber meine ist die beste;)

<?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

Dies ist auch möglich. Es wird Englisch als Standard verwendet, wenn .php nicht verfügbar ist.

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