有没有一种简单的方法可以从 PHP 中的国家/地区代码中获取语言代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10175658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a simple way to get the language code from a country code in PHP
提问by codecowboy
I'm using ISO 3166-1-alpha 2 codes to pass to an application to retrieve a localised feed e.g. /feeds/us for the USA. I have a switch statement which serves a feed based on that country_code.
我正在使用 ISO 3166-1-alpha 2 代码传递给应用程序以检索本地化的提要,例如美国的 /feeds/us。我有一个 switch 语句,它提供基于该 country_code 的提要。
Is there a way to convert that two digit code to the language code e.g. en_US ? I'm wondering if there is a standard / function / library for doing this in PHP or whether I need to build my own array?
有没有办法将该两位数代码转换为语言代码,例如 en_US ?我想知道是否有一个标准/函数/库可以在 PHP 中执行此操作,或者我是否需要构建自己的数组?
采纳答案by TheJF
As other have pointed out, there is no built-in function as this likely due to the reality of many countries having multiple languages. So unfortunately, I can't point you to a library that does this, but I did go ahead and write a little function which does what you want.
正如其他人指出的那样,没有内置功能,这可能是由于许多国家/地区拥有多种语言的现实。因此,不幸的是,我无法向您指出执行此操作的库,但我确实继续编写了一个可以执行您想要的操作的小函数。
There are two caveats, one being if it isn't provided a language it will just pick the first locale in the list. To get around this, you'd have to put some logic around the function call to provide it with the appropriate language. The other is that it needs to have php5-intl installed.
有两个警告,一个是如果它没有提供一种语言,它只会选择列表中的第一个语言环境。为了解决这个问题,您必须在函数调用周围放置一些逻辑,以为其提供适当的语言。另一个是它需要安装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;
}
?>
回答by Mikko Rantalainen
You cannot automatically convert country code to language code because some countries use multiple languages. On the other hand, OS localization system may support multiple variants of a single language for different countries (for example, en_GB vs en_US).
您无法自动将国家代码转换为语言代码,因为某些国家/地区使用多种语言。另一方面,操作系统本地化系统可能支持不同国家的单一语言的多种变体(例如,en_GB 与 en_US)。
For example, Switzerland (CH) has both German and French commonly used (64% and 20% of the population, according to http://en.wikipedia.org/wiki/Switzerland). If you have to decide a single language for country code CH either of those languages could make sense for some people. Note that some parts of the Switzerland use only German or French as the official language (but not both, see http://en.wikipedia.org/wiki/File:Sprachen_CH_2000_EN.svgfor details).
例如,瑞士 (CH) 常用德语和法语(根据http://en.wikipedia.org/wiki/Switzerland 的数据,分别占人口的 64% 和 20% )。如果您必须为国家/地区代码 CH 确定一种语言,那么对于某些人来说,这两种语言中的任何一种都可能有意义。请注意,瑞士的某些地区仅使用德语或法语作为官方语言(但不能同时使用两者,详情请参见http://en.wikipedia.org/wiki/File:Sprachen_CH_2000_EN.svg)。
If you MUST select a single language for each country, I'd suggest doing the selection by hand for every country you support. For an half-assed automatic implementation, you could scan through your available localizations and select the first one that has the matching country code after the underscore.
如果您必须为每个国家/地区选择一种语言,我建议您为您支持的每个国家/地区手动选择。对于半途而废的自动实施,您可以浏览可用的本地化并选择下划线后具有匹配国家/地区代码的第一个。
回答by ausi
As noted by other answers there is no one to one mapping between countries and languages. However, if you have the PHP Intlextension installed it should be possible to use the Unicode CLDR likely subtags datato get the “default” or “likely” language for a specific country:
正如其他答案所指出的,国家和语言之间没有一对一的映射。但是,如果您安装了 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);
}
Now when you call the getLanguage()function with a country code you get the according language code back:
现在,当您getLanguage()使用国家/地区代码调用该函数时,您将获得相应的语言代码:
getLanguage('US'); // "en"
getLanguage('GB'); // "en"
getLanguage('DE'); // "de"
getLanguage('CH'); // "de"
getLanguage('IN'); // "hi"
getLanguage('NO'); // "nb"
getLanguage('BR'); // "pt"
This also works fine for three letter country codes:
这也适用于三个字母的国家/地区代码:
getLanguage('USA'); // "en"
getLanguage('GBR'); // "en"
getLanguage('AUT'); // "de"
getLanguage('FRA'); // "fr"
And even UN M49codes:
甚至联合国 M49代码:
getLanguage('003'); // "en"
getLanguage('013'); // "es"
getLanguage('039'); // "it"
getLanguage('155'); // "de"
回答by AO_
You will want to cross reference these files:
您需要交叉引用这些文件:
http://www.ethnologue.com/codes/LanguageIndex.tabhttp://www.ethnologue.com/codes/CountryCodes.tabhttp://www.ethnologue.com/codes/LanguageCodes.tab
..or get them all in one zip here: http://www.ethnologue.com/codes/Language_Code_Data_20110104.zip
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
There is no current set PHP function that returns this data that I'm aware of.
没有当前设置的 PHP 函数可以返回我所知道的这些数据。
回答by Eugen
the answer from TheJFis pretty good, however there are a few (general) issues that I came across:
his code will return
br-FRif you callcountry_code_to_locale("FR")- nowbr(Breton) is not even an offical language according to Wikipedia. Althoughfr-FRis in the list,br-FRis the first in the array. this happens with many other countries too.many other locale lists are trying to be extremly complete and consider all possible languages
it is difficult to draw the line here, good examples where you certainly want to keep multiple languages for a country are: Canada and Switzerland
br-FR如果你打电话,他的代码会返回country_code_to_locale("FR")-br根据维基百科,现在(布列塔尼)甚至不是官方语言。虽然fr-FR在列表中,br-FR但在数组中是第一个。这也发生在许多其他国家。许多其他语言环境列表正试图非常完整并考虑所有可能的语言
在这里很难划清界限,您当然希望为一个国家/地区保留多种语言的好例子是:加拿大和瑞士
I went with a simple approach:
我采用了一种简单的方法:
I kept only 1 language for most countries, and left multiple for some countries like BE, CA, CH, ZA. I kept
es-US, but I am not sure about that (Wikipedia says:Official languages: None at federal level)I also kept multiple languages for countries I was too lazy to research or that use both, Latin and Cyrillic
I added
shuffle($locales);which will randomize the array, such that we get random locales for countries with multiple languages. It made sense for my use case, but you might want to remove that.For my purpose, only languages that have relevant prevalence on the web are of interest. This list is by no means complete or correct, but pragmatic.
我只为大多数国家/地区保留了一种语言,并为 BE、CA、CH、ZA 等一些国家/地区保留了多种语言。我不停的
es-US,但我不知道这一点(维基百科说:Official languages: None at federal level)我还为我懒得研究或同时使用拉丁语和西里尔语的国家/地区保留了多种语言
我添加了
shuffle($locales);which 将随机化数组,以便我们为具有多种语言的国家/地区获得随机区域设置。这对我的用例很有意义,但您可能想删除它。就我而言,只有在网络上流行的语言才有意义。这份清单绝不是完整或正确的,而是务实的。
So here is my locale list:
所以这是我的语言环境列表:
$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');
and the code:
和代码:
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";
}

