Im hobbycoder, который пытается построить свой первый многоязычный сайт
Я использую этот фрагмент кода для определения языка пользователей. Если вы не выбрали язык, он будет включать в себя ваш языковой файл на основе 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');
Он работает для меня и включает файл polish lang. Но точно ли этот код? Или есть другой способ? Как вы думаете, что YouTube делает это, например?
Было бы здорово, если бы некоторые английские, французские, шведские или польский люди могли посетить мой сайт и посмотреть, включает ли он правильный файл! Так что я знаю, что он просто не работает для меня 🙂 http://jorm.homeftp.org/
В любом случае, вы думаете, что я мог бы улучшить свой код? это будет выглядеть грязно, поскольку я добавляю больше языков со всеми этими elseif!
благодаря
Браузер обычно отправляет 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 для определения языка пользователя
Повеселись !
Вы можете использовать: Locale::acceptFromHttp()
.
Пытается найти локаль, которая может удовлетворить список языков, который запрашивается заголовком HTTP-Accept-Language.
Вот сценарий, который я использовал для двуязычного сайта. Он должен использоваться как index.php
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]); ?>
Я знаю, что есть много хороших решений, но мой лучший;)
<?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 */
Ваш код выглядит просто отлично. Возможно, вы захотите добавить окончательный вариант по умолчанию, если посетитель попросит указать язык, который вы не предоставляете. Кроме того, если посетитель сам выбирает язык, вы должны сохранить этот выбор в постоянном cookie и проверить его значение, придав ему приоритет над HTTP_ACCEPT_LANGUAGE.
Насколько я могу судить, Youtube использует HTTP_ACCEPT_LANGUAGE, но в то же время использует геолокацию IP, чтобы предлагать изменение языка, если langauge страны посетителя не соответствует этому. Определенно раздражает.
Просто nitpicking: если вы собираетесь добавлять языки в список, оператор switch()
может быть более читаемым.
Попробуй это
function getUserLanguage() { $langs = array(); if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { // break up string into pieces (languages and q factors) preg_match_all( '/([az]{1,8}(-[az]{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; }
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){ $parts=explode(';',$_SERVER['HTTP_ACCEPT_LANGUAGE']); $langs=explode(',',$parts[0]); var_dump($langs); }
Это также возможно. Он будет использовать английский по умолчанию, если .php недоступен.
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); (@include_once 'languages/'.$lang.'.php') or (@include_once 'languages/en.php');