Есть ли простой способ получить код языка из кода страны в PHP


Я использую коды ISO 3166-1-альфа 2 для передачи приложению для получения локализованного канала, например /каналы/сша для США. У меня есть оператор switch, который обслуживает канал на основе этого кода страны.

Есть ли способ преобразовать этот двухзначный код в код языка, например en_US? Мне интересно, есть ли стандарт/функция/библиотека для этого в PHP или мне нужно создать свой собственный массив?

 12
Author: codecowboy, 2012-04-16

4 answers

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

Есть два предостережения, одно из которых заключается в том, что если язык не указан, он просто выберет первую локаль в списке. Чтобы обойти это, вам придется применить некоторую логику к вызову функции, чтобы обеспечить его с соответствующим языком. Другой заключается в том, что для этого необходимо установить php5-intl.

<?php

/**
/* Returns a locale from a country code that is provided.
/*
/* @param $country_code  ISO 3166-2-alpha 2 country code
/* @param $language_code ISO 639-1-alpha 2 language code
/* @returns  a locale, formatted like en_US, or null if not found
/**/
function country_code_to_locale($country_code, $language_code = '')
{
    // Locale list taken from:
    // http://stackoverflow.com/questions/3191664/
    // list-of-all-locales-and-their-short-codes
    $locales = array('af-ZA',
                    'am-ET',
                    'ar-AE',
                    'ar-BH',
                    'ar-DZ',
                    'ar-EG',
                    'ar-IQ',
                    'ar-JO',
                    'ar-KW',
                    'ar-LB',
                    'ar-LY',
                    'ar-MA',
                    'arn-CL',
                    'ar-OM',
                    'ar-QA',
                    'ar-SA',
                    'ar-SY',
                    'ar-TN',
                    'ar-YE',
                    'as-IN',
                    'az-Cyrl-AZ',
                    'az-Latn-AZ',
                    'ba-RU',
                    'be-BY',
                    'bg-BG',
                    'bn-BD',
                    'bn-IN',
                    'bo-CN',
                    'br-FR',
                    'bs-Cyrl-BA',
                    'bs-Latn-BA',
                    'ca-ES',
                    'co-FR',
                    'cs-CZ',
                    'cy-GB',
                    'da-DK',
                    'de-AT',
                    'de-CH',
                    'de-DE',
                    'de-LI',
                    'de-LU',
                    'dsb-DE',
                    'dv-MV',
                    'el-GR',
                    'en-029',
                    'en-AU',
                    'en-BZ',
                    'en-CA',
                    'en-GB',
                    'en-IE',
                    'en-IN',
                    'en-JM',
                    'en-MY',
                    'en-NZ',
                    'en-PH',
                    'en-SG',
                    'en-TT',
                    'en-US',
                    'en-ZA',
                    'en-ZW',
                    'es-AR',
                    'es-BO',
                    'es-CL',
                    'es-CO',
                    'es-CR',
                    'es-DO',
                    'es-EC',
                    'es-ES',
                    'es-GT',
                    'es-HN',
                    'es-MX',
                    'es-NI',
                    'es-PA',
                    'es-PE',
                    'es-PR',
                    'es-PY',
                    'es-SV',
                    'es-US',
                    'es-UY',
                    'es-VE',
                    'et-EE',
                    'eu-ES',
                    'fa-IR',
                    'fi-FI',
                    'fil-PH',
                    'fo-FO',
                    'fr-BE',
                    'fr-CA',
                    'fr-CH',
                    'fr-FR',
                    'fr-LU',
                    'fr-MC',
                    'fy-NL',
                    'ga-IE',
                    'gd-GB',
                    'gl-ES',
                    'gsw-FR',
                    'gu-IN',
                    'ha-Latn-NG',
                    'he-IL',
                    'hi-IN',
                    'hr-BA',
                    'hr-HR',
                    'hsb-DE',
                    'hu-HU',
                    'hy-AM',
                    'id-ID',
                    'ig-NG',
                    'ii-CN',
                    'is-IS',
                    'it-CH',
                    'it-IT',
                    'iu-Cans-CA',
                    'iu-Latn-CA',
                    'ja-JP',
                    'ka-GE',
                    'kk-KZ',
                    'kl-GL',
                    'km-KH',
                    'kn-IN',
                    'kok-IN',
                    'ko-KR',
                    'ky-KG',
                    'lb-LU',
                    'lo-LA',
                    'lt-LT',
                    'lv-LV',
                    'mi-NZ',
                    'mk-MK',
                    'ml-IN',
                    'mn-MN',
                    'mn-Mong-CN',
                    'moh-CA',
                    'mr-IN',
                    'ms-BN',
                    'ms-MY',
                    'mt-MT',
                    'nb-NO',
                    'ne-NP',
                    'nl-BE',
                    'nl-NL',
                    'nn-NO',
                    'nso-ZA',
                    'oc-FR',
                    'or-IN',
                    'pa-IN',
                    'pl-PL',
                    'prs-AF',
                    'ps-AF',
                    'pt-BR',
                    'pt-PT',
                    'qut-GT',
                    'quz-BO',
                    'quz-EC',
                    'quz-PE',
                    'rm-CH',
                    'ro-RO',
                    'ru-RU',
                    'rw-RW',
                    'sah-RU',
                    'sa-IN',
                    'se-FI',
                    'se-NO',
                    'se-SE',
                    'si-LK',
                    'sk-SK',
                    'sl-SI',
                    'sma-NO',
                    'sma-SE',
                    'smj-NO',
                    'smj-SE',
                    'smn-FI',
                    'sms-FI',
                    'sq-AL',
                    'sr-Cyrl-BA',
                    'sr-Cyrl-CS',
                    'sr-Cyrl-ME',
                    'sr-Cyrl-RS',
                    'sr-Latn-BA',
                    'sr-Latn-CS',
                    'sr-Latn-ME',
                    'sr-Latn-RS',
                    'sv-FI',
                    'sv-SE',
                    'sw-KE',
                    'syr-SY',
                    'ta-IN',
                    'te-IN',
                    'tg-Cyrl-TJ',
                    'th-TH',
                    'tk-TM',
                    'tn-ZA',
                    'tr-TR',
                    'tt-RU',
                    'tzm-Latn-DZ',
                    'ug-CN',
                    'uk-UA',
                    'ur-PK',
                    'uz-Cyrl-UZ',
                    'uz-Latn-UZ',
                    'vi-VN',
                    'wo-SN',
                    'xh-ZA',
                    'yo-NG',
                    'zh-CN',
                    'zh-HK',
                    'zh-MO',
                    'zh-SG',
                    'zh-TW',
                    'zu-ZA',);

    foreach ($locales as $locale)
    {
        $locale_region = locale_get_region($locale);
        $locale_language = locale_get_primary_language($locale);
        $locale_array = array('language' => $locale_language,
                             'region' => $locale_region);

        if (strtoupper($country_code) == $locale_region &&
            $language_code == '')
        {
            return locale_compose($locale_array);
        }
        elseif (strtoupper($country_code) == $locale_region &&
                strtolower($language_code) == $locale_language)
        {
            return locale_compose($locale_array);
        }
    }

    return null;
}
?>
 13
Author: TheJF, 2012-04-29 19:28:06

Вы не можете автоматически преобразовать код страны в код языка, поскольку в некоторых странах используется несколько языков. С другой стороны, система локализации ОС может поддерживать несколько вариантов одного языка для разных стран (например, en_GB против en_US).

Например, в Швейцарии (CH) широко используются как немецкий, так и французский языки (64 % и 20 % населения, согласно http://en.wikipedia.org/wiki/Switzerland ). Если вам нужно выбрать один язык для код страны CH на любом из этих языков может иметь смысл для некоторых людей. Обратите внимание, что в некоторых частях Швейцарии в качестве официального языка используется только немецкий или французский (но не оба, см. http://en.wikipedia.org/wiki/File:Sprachen_CH_2000_EN.svg подробнее).

Если вам НЕОБХОДИМО выбрать один язык для каждой страны, я бы предложил сделать выбор вручную для каждой страны, которую вы поддерживаете. Для полуавтоматической автоматической реализации вы можете сканировать доступные локализации и выберите первую, у которой есть соответствующий код страны после подчеркивания.

 4
Author: Mikko Rantalainen, 2012-04-27 06:09:07

Вам понадобится перекрестная ссылка на эти файлы:

Http://www.ethnologue.com/codes/LanguageIndex.tab http://www.ethnologue.com/codes/CountryCodes.tab http://www.ethnologue.com/codes/LanguageCodes.tab

..или получите их все в одном почтовом ящике здесь: http://www.ethnologue.com/codes/Language_Code_Data_20110104.zip

Насколько мне известно, не существует текущей функции PHP set, которая возвращает эти данные.

 0
Author: Andrew Odendaal, 2012-04-26 00:32:30

Ответ от JF довольно хорош, однако есть несколько (общих) проблем, с которыми я столкнулся:

  • Его код вернет br-FR, если вы вызовете country_code_to_locale("FR") - теперь br (бретонский) даже не является официальным языком, согласно Википедии. Хотя fr-FR находится в списке, br-FR является первым в массиве. это происходит и со многими другими странами.

  • Многие другие списки локали стараются быть максимально полными и учитывать все возможные языки

  • Здесь трудно провести черту, хорошими примерами, в которых вы, безусловно, хотите сохранить несколько языков для одной страны, являются: Канада и Швейцария

Я выбрал простой подход:

  • Я сохранил только 1 язык для большинства стран и оставил несколько для некоторых стран, таких как BE, CA, CH, ZA. Я сохранил es-US, но я не уверен в этом (Википедия говорит: Official languages: None at federal level)

  • Я также сохранил несколько языков для стран, которые мне было лень исследовать, или которые используют и латиницу, и кириллицу

  • Я добавил shuffle($locales);, который будет рандомизировать массив, так что мы получим случайные локали для стран с несколькими языками. Это имело смысл для моего варианта использования, но вы, возможно, захотите удалить это.

  • Для моей цели представляют интерес только те языки, которые имеют соответствующую распространенность в Интернете. Этот список ни в коем случае не является полным или правильным, но прагматичный.

Итак, вот мой список локали:

$locales = array('af-ZA',
                'am-ET',
                'ar-AE',
                'ar-BH',
                'ar-DZ',
                'ar-EG',
                'ar-IQ',
                'ar-JO',
                'ar-KW',
                'ar-LB',
                'ar-LY',
                'ar-MA',
                'ar-OM',
                'ar-QA',
                'ar-SA',
                'ar-SY',
                'ar-TN',
                'ar-YE',
                'az-Cyrl-AZ',
                'az-Latn-AZ',
                'be-BY',
                'bg-BG',
                'bn-BD',
                'bs-Cyrl-BA',
                'bs-Latn-BA',
                'cs-CZ',
                'da-DK',
                'de-AT',
                'de-CH',
                'de-DE',
                'de-LI',
                'de-LU',
                'dv-MV',
                'el-GR',
                'en-AU',
                'en-BZ',
                'en-CA',
                'en-GB',
                'en-IE',
                'en-JM',
                'en-MY',
                'en-NZ',
                'en-SG',
                'en-TT',
                'en-US',
                'en-ZA',
                'en-ZW',
                'es-AR',
                'es-BO',
                'es-CL',
                'es-CO',
                'es-CR',
                'es-DO',
                'es-EC',
                'es-ES',
                'es-GT',
                'es-HN',
                'es-MX',
                'es-NI',
                'es-PA',
                'es-PE',
                'es-PR',
                'es-PY',
                'es-SV',
                'es-US',
                'es-UY',
                'es-VE',
                'et-EE',
                'fa-IR',
                'fi-FI',
                'fil-PH',
                'fo-FO',
                'fr-BE',
                'fr-CA',
                'fr-CH',
                'fr-FR',
                'fr-LU',
                'fr-MC',
                'he-IL',
                'hi-IN',
                'hr-BA',
                'hr-HR',
                'hu-HU',
                'hy-AM',
                'id-ID',
                'ig-NG',
                'is-IS',
                'it-CH',
                'it-IT',
                'ja-JP',
                'ka-GE',
                'kk-KZ',
                'kl-GL',
                'km-KH',
                'ko-KR',
                'ky-KG',
                'lb-LU',
                'lo-LA',
                'lt-LT',
                'lv-LV',
                'mi-NZ',
                'mk-MK',
                'mn-MN',
                'ms-BN',
                'ms-MY',
                'mt-MT',
                'nb-NO',
                'ne-NP',
                'nl-BE',
                'nl-NL',
                'pl-PL',
                'prs-AF',
                'ps-AF',
                'pt-BR',
                'pt-PT',
                'ro-RO',
                'ru-RU',
                'rw-RW',
                'sv-SE',
                'si-LK',
                'sk-SK',
                'sl-SI',
                'sq-AL',
                'sr-Cyrl-BA',
                'sr-Cyrl-CS',
                'sr-Cyrl-ME',
                'sr-Cyrl-RS',
                'sr-Latn-BA',
                'sr-Latn-CS',
                'sr-Latn-ME',
                'sr-Latn-RS',
                'sw-KE',
                'tg-Cyrl-TJ',
                'th-TH',
                'tk-TM',
                'tr-TR',
                'uk-UA',
                'ur-PK',
                'uz-Cyrl-UZ',
                'uz-Latn-UZ',
                'vi-VN',
                'wo-SN',
                'yo-NG',
                'zh-CN',
                'zh-HK',
                'zh-MO',
                'zh-SG',
                'zh-TW');

И код:

function country_code_to_locale($country_code)
{
    $locales = ...

    // randomize the array, such that we get random locales
    // for countries with multiple languages (CA, CH)
    shuffle($locales);

    foreach ($locales as $locale) {
        $locale_region = locale_get_region($locale);

        if (strtoupper($country_code) == $locale_region) {
            return $locale;
        }
    }

    return "en-US";
}
 0
Author: Eugen, 2017-08-03 23:49:44