Грамотне визначення мови користувача, savepearlharbor

Грамотне визначення мови користувача, savepearlharbor
Зараз працюю над сайтом, який претендує на глобальність, природно і з мультиязичностью у нього має бути все в порядку.

Про те як відображати інформацію на різних мовах тут мови йти не буде. Розмова піде про те як визначити мову користувача, і вибрати з доступних на сайті мовних версій найбільш підходящу.

І так що маємо:

  • PHP
  • Фреймворк CodeIgniter (клас писався для цього фреймворку, але його можна використовувати де завгодно, внісши невеликі зміни)

завдання:
Визначити мову користувача і якщо користувач украінскоговорящій (український, Беларус, Українець повний список тут) показуємо йому інформацію російською. Якщо немає то англійською.
Все це потрібно оформити у вигляді класу або функції з можливістю швидко задавати щось на зразок посилань з мови користувача на мову кращий для його розуміння на сайті.

Рішення:
Для визначення мови користувача використовуємо суперглобальний масив $ _SERVER, а точніше - його елемент $ _SERVER [ 'HTTP_ACCEPT_LANGUAGE'] в ньому описуються переваги клієнта щодо мови. Дана інформація витягується з HTTP-заголовка Accept-Language, який надсилає клієнт сервера.
У моєму випадку це був рядок

Цей рядок містить мови користувача, які він вважає за краще, і їх пріоритети виражаються через q, їли q для мови не задано, то мається на увазі, що воно буде дорівнює 1. Якщо постаратися відобразити її в більш менш Новомосковскемом вигляді то вона виглядає так:

Звідси видно що я вважаю за краще українську мову, а на другому місці у мене англійська.
Мови написані в двох форматах головний код мови це «ru» і «en» в моєму випадку, який відноситься до язикоивм стандартам ISO 639
І головний код мови - розширений код мови в моєму випадку це «ru-ru» і «en-us» тут розширений код мови вказує на регіон використання мови у мене це United States.
Часом виникає непорозуміння з тим як помітити мови, коли списки кодів ISO містять як дволітерні так і трьохбуквені коди (іноді кілька трибуквених кодів). Зараз всі дійсні коди перераховані в одному IANA реєстрі. який для мови приймає тільки одне значення зі списків ISO. Якщо доступний двобуквений код ISO, то він буде один в реєстрі. Інакше реєстр міститиме один трилітерний код. Це спростить речі.

З теорією розібралися переходимо до практики:
Напишемо конструктор контролера класу:

Тут ми обробляємо рядок возвращаемую $ _SERVER [ 'HTTP_ACCEPT_LANGUAGE'] так щоб це вийшов масив виду

Відсортований за спаданням пріоритету мови (значення q)

Далі створюємо метод знаходить найбільш підходящий мову.
Першим пареметром в неї передається мова буде використовуватися під, другим масив ключами якого будуть мови які є на сайті, а значеннями посилання на нього з інших мов виглядає масив приблизно так:

У функції урізаються мови формату головний код мови - розширений код мови до формату головний код мови тому необхідність в Англійській і Американської версії мови врядли виникне, а при бажанні завжди можна дописати.
Результатом її виконання буде найбільш підходящий мову користувача, в форматі ISO 639 в якості дефолтного мови я передав англійська, і для всег мов що не перебувають в масиві $ langs буде повернутий en.

Завантажити бібліотечку можна тут