Получить стандартную локаль для языка в PHP

У меня есть PHP-сервер, с которым взаимодействует несколько типов устройств через открытый API. Обычно запросы содержат требуемый язык для ответа (например, «en» или «fr» или «ru» и т. Д.), Но не полный язык. За последние пару лет это отлично справилось со всем, что мне нужно. Однако теперь мне нужно включить информацию о дате в ответ – и мне нужен языковой стандарт для форматирования дат.

Как я могу получить языковой стандарт? Я понимаю, что языка недостаточно, чтобы однозначно идентифицировать локаль, но мне нужно хотя бы что-то. Если я могу получить хотя бы один язык, например en_GB для 'en' или 'ru_RU' для 'ru' и т. Д., Этого было бы достаточно.

Подумав больше о проблеме и конкретной установке, которую я имею, я придумал это решение, которое, похоже, работает. Обратите внимание, что я не контролирую, какие языки мне нужно поддерживать: файлы перевода упали в предопределенное место и локали системы, установленные кем-то другим. Во время выполнения я должен поддерживать определенный язык, если существует соответствующий файл перевода и установлен языковой стандарт системы. Это привело меня к такому решению:

function getLocale($lang) { $locs = array(); exec('locale -a', $locs); $locale = 'en_GB'; foreach($locs as $l) { $regex = "/$lang\_[AZ]{2}$/"; if(preg_match($regex, $l) && file_exists(TRANSROOT . "/$lang.php")) { $locale = $l; break; } } return $locale; } 

Я по умолчанию для en_GB, если я не могу решить локаль, потому что я точно знаю, что en_GB установлен (мы находимся в Великобритании, как и наши серверы).

Возможно, вы можете использовать $_SERVER['HTTP_ACCEPT_LANGUAGE']; вместо поставляемого языка, чтобы получить локаль. Довольно часто это будет содержать фактический язык с дефисом вместо подчеркивания.

Пример $_SERVER['HTTP_ACCEPT_LANGUAGE'] :

en-ca,en;q=0.8,fr-ca;q=0.5,fr;q=0.3

Просто получите все до первого , и все готово. Это также лучше, чем заполнение массива локалей, поскольку он позволяет браузеру сообщать серверу, какой язык он предпочитает, а не наоборот, однако массив, как в ответе hakre, должен использоваться как резервная система в случае недопустимого / пустого / отсутствует $_SERVER['HTTP_ACCEPT_LANGUAGE'] .

Что-то еще, что вы можете захотеть изучить, – это класс локали и, возможно, метод locale :: acceptFromHttp

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

Я правильно понимаю, что вам нужна только карта с языка (например, en ) в локали (например, en_GB )? Если это так, вы можете скомпилировать его для языков, которые вы используете:

 $localeMap = array( 'en' => 'en_GB', 'fr' => 'fr_FR', # ... ); # Usage: $locale = $localeMap[$lang]; 

Но это так тривиально, что я не уверен, правильно ли понял ваш вопрос.

Если вы не знаете, какой язык для языка, просто возьмите язык, который должен быть действительным языком, без страны:

l => l l

Пока язык в двухбуквенном формате отлично подходит для меня (стандарт ISO 639, «Код для представления имен языков»), см. Также « Теги для идентификации языков» (RFC 1766) .

 $locale = isset($localeMap[$lang]) ? $localeMap[$lang] : $lang; 

Однако это может различаться в зависимости от того, какой формат языка использует ожидаемая вами функция.


 class System { /** * @return array */ public function getLocales() { $locales = array(); exec('locale -a', $locales, $retCode); !$retCode || $locales = array(); return $locales; } /** * @return string something matching * @note Improve by creating your system aware locale class to move * away the responsibility to map system locales onto strings * of certain kinds and to deal with the different locale types. */ public function getLocaleByLang($lang) { ... } } $lang = ... $system = new System; $locale = $system->getLocaleByLang($lang);