ISO 3166-1-alpha 2コードを使用してアプリケーションに渡し、ローカライズされたフィード(たとえば、米国の/ feeds / us)を取得しています。そのcountry_codeに基づいてフィードを提供するswitchステートメントがあります。
その2桁のコードをen_USなどの言語コードに変換する方法はありますか?PHPでこれを行うための標準/関数/ライブラリがあるかどうか、または独自の配列を作成する必要があるかどうか疑問に思っていますか?
他の人が指摘しているように、これはおそらく複数の言語を持っている多くの国の現実のために、組み込みの機能はありません。残念ながら、これを実行するライブラリを紹介することはできませんが、先に進んで、必要なことを実行する小さな関数を作成しました。
2つの注意点があります。1つは、言語が提供されていない場合、リストの最初のロケールを選択するだけです。これを回避するには、関数呼び出しの周りにロジックを配置して、適切な言語を提供する必要があります。もう1つは、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;
}
?>
国によっては複数の言語を使用しているため、国コードを言語コードに自動的に変換することはできません。一方、OSローカリゼーションシステムは、国ごとに1つの言語の複数のバリアントをサポートする場合があります(たとえば、en_GBとen_US)。
たとえば、スイス(CH)ではドイツ語とフランス語の両方が一般的に使用されています(http://en.wikipedia.org/wiki/Switzerlandによると、人口の64%と20% )。国コードCHの単一の言語を決定する必要がある場合、これらの言語のいずれかが一部の人にとって意味をなす可能性があります。スイスの一部の地域では、公用語としてドイツ語またはフランス語のみが使用されていることに注意してください(両方ではありません。詳細については、 http://en.wikipedia.org/wiki/File:Sprachen_CH_2000_EN.svgを参照してください)。
国ごとに1つの言語を選択する必要がある場合は、サポートするすべての国で手動で選択することをお勧めします。中途半端な自動実装の場合は、利用可能なローカリゼーションをスキャンして、アンダースコアの後に国コードが一致する最初のローカリゼーションを選択できます。
また、当然の結果として、言語と国には1:1の関係がないため、言語を国旗で表すことはできません。1対多の関係は両方向に見られます。
他の回答で指摘されているように、国と言語の間に1対1のマッピングはありません。ただし、PHPIntl
拡張機能がインストールされている場合は、Unicode CLDRの可能性のあるサブタグデータを使用して、特定の国の「デフォルト」または「可能性の高い」言語を取得できるはずです。
function getLanguage(string $country): string {
$subtags = \ResourceBundle::create('likelySubtags', 'ICUDATA', false);
$country = \Locale::canonicalize('und_'.$country);
$locale = $subtags->get($country) ?: $subtags->get('und');
return \Locale::getPrimaryLanguage($locale);
}
これで、国コードを使用して関数を呼び出すと、getLanguage()
対応する言語コードが返されます。
getLanguage('US'); // "en"
getLanguage('GB'); // "en"
getLanguage('DE'); // "de"
getLanguage('CH'); // "de"
getLanguage('IN'); // "hi"
getLanguage('NO'); // "nb"
getLanguage('BR'); // "pt"
これは、3文字の国コードでも正常に機能します。
getLanguage('USA'); // "en"
getLanguage('GBR'); // "en"
getLanguage('AUT'); // "de"
getLanguage('FRA'); // "fr"
そして、UN M49コードでさえ:
getLanguage('003'); // "en"
getLanguage('013'); // "es"
getLanguage('039'); // "it"
getLanguage('155'); // "de"
これらのファイルを相互参照する必要があります。
http://www.ethnologue.com/codes/LanguageIndex.tab http://www.ethnologue.com/codes/CountryCodes.tab http://www.ethnologue.com/codes/LanguageCodes.tab
..または、ここですべてを1つのzipにまとめます: http://www.ethnologue.com/codes/Language_Code_Data_20110104.zip
私が知っているこのデータを返す現在設定されているPHP関数はありません。
TheJFからの回答はかなり良いですが、私が遭遇したいくつかの(一般的な)問題があります:
ウィキペディアによると、今(ブルトン語)は公式言語でさえありませ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);
を取得するように、配列をランダム化するものを追加しました。私のユースケースではそれは理にかなっていますが、それを削除することをお勧めします。
私の目的では、Web上で関連する普及率を持つ言語のみが対象となります。このリストは決して完全または正しいものではありませんが、実用的です。
これが私のロケールリストです:
$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";
}