Подтвердить что ты не робот

Определение языка PHP

Я пытаюсь создать многоязычный сайт.

Я использую этот кусок кода для определения языка пользователя. Если вы не выбрали язык, он будет включать ваш языковой файл на основе HTTP_ACCEPT_LANGUAGE.

Хотя я не знаю, откуда он это взял:

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

Это работает для меня и включает в себя файл польского языка. Но точен ли этот код? Или есть другой способ?

4b9b3361

Ответ 1

Браузер обычно отправляет HTTP-заголовок, имя Accept-Language, который указывает, какие языки пользователь хочет получить.

Например, этот заголовок может быть:

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

В нем есть понятие приоритета, btw; -)

В PHP вы можете получить это в супер-глобальном $_SERVER:

var_dump($_SERVER['HTTP_ACCEPT_LANGUAGE']);

получит меня:

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

Теперь вам нужно разобрать это: -)


Если я отредактирую свои предпочтения в опции браузера, чтобы сказать "Я хочу французский, и если вы не можете служить мне на французском языке, заведите меня в английский язык из США, и если вы не сможете это получить, просто приведите меня английский), заголовок будет:

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

И, из PHP:

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


Дополнительную информацию можно найти в разделе раздела 14.4 HTTP RFC.

И вы, вероятно, найдете много примеров кода в PHP для разбора этого заголовка; например: Parse Accept-Language для определения языка пользователя

Удачи!

Ответ 2

Здесь script я использовал для двуязычного сайта. Он должен использоваться как index.php of mysite.com. Основываясь на предпочтениях браузера пользователя, он перенаправляет на желаемую языковую версию сайта или языка языка по умолчанию, если сайт в предпочитаемом пользователем langauge не был доступен.

<?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]);
?>

Ответ 3

Вы можете использовать: Locale::acceptFromHttp().

Пытается найти язык, который может удовлетворить языковой список, который запрашивается заголовком HTTP-Accept-Language.

Ответ 4

Я знаю, что там уже много хороших решений, но нашел свой способ решить эту проблему.

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

Код преобразует строку HTTP_ACCEPT_LANGUAGE в массив с локалями в качестве ключей и весом в качестве значений, отсортированных от высокого значения к низкому. Таким образом, вы можете просто получить один за другим с array_shift, чтобы получить лучшее соответствие с языком вашего сайта.

Ответ 5

Ваш код выглядит просто отлично. Возможно, вы захотите добавить окончательный вариант else по умолчанию, если посетитель попросит указать язык, который вы не предоставляете. Кроме того, если посетитель сам выбирает язык, вы должны сохранить этот выбор в постоянном cookie и проверить его значение, придав ему приоритет над HTTP_ACCEPT_LANGUAGE.

Насколько я могу судить, Youtube использует HTTP_ACCEPT_LANGUAGE, но в то же время использует геолокацию IP, чтобы предлагать изменение языка, если langauge страны посетителя не соответствует этому. Определенно раздражает.

Просто nitpicking: если вы собираетесь добавлять языки в список, оператор switch() может быть более читаемым.

Ответ 6

Попробуйте это

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;
}

Ответ 7

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

Ответ 8

Это также возможно. Он будет использовать английский по умолчанию, если .php недоступен.

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