共计 5051 个字符,预计需要花费 13 分钟才能阅读完成。
置信大家对 zh_CN 这个货色相对不会生疏,不论是 PHP 中,还是在咱们的网页上,都会见到它的身影。其实这就是指定咱们的显示编码是什么国家或者地区的,应用何种语言。对于这种区域语言的标记来说,PHP 中也有很多好玩的内容。明天,咱们要学习的 Locale 类就是操作区域语言相干内容的,它无奈被实例化,所有全副性能办法都是动态的。
获取及设置以后的区域语言信息
首先就是咱们能够动静地获取和设置相应的区域语言信息。
// # echo $LANG;
// en_US.UTF-8
// php.ini
// intl.default_locale => no value => no value
echo Locale::getDefault(), PHP_EOL; // en_US_POSIX
ini_set('intl.default_locale', 'zh_CN');
echo Locale::getDefault(), PHP_EOL; // zh_CN
Locale::setDefault('fr');
echo Locale::getDefault(), PHP_EOL; // fr
默认状况下,应用 getDefault() 办法取得的是 php.ini 文件中的 intl.default_locale 配置的内容。如果在 php.ini 中也没有配置的话,就会取操作系统的 $LANG 值外面的内容,也就是咱们下面例子中输入的 en_US_POSIX,POSIX 示意的就是来自操作系统的配置。
应用 ini_set() 间接批改 ini 的配置或者应用 setDefault() 办法都是能够动静地批改以后的区域语言设置的。
对于语言标记的规定
在持续学习上面的内容之前,咱们先来学习一下语言标记的标准。对于大多数人来说,可能只接触过 en_US、zh_CN 这类的标记,但其实它的残缺定义是很长的,只是咱们应用这种简写的形式时,很多内容会以默认的模式提供。残缺的标记规定是:
language-extlang-script-region-variant-extension-privateuse
语言文字品种 - 扩大语言文字品种 - 书写格局 - 国家和地区 - 变体 - 扩大 - 公有
也就是说,咱们的 zh_CN 能够这样写:
zh-cmn-Hans-CN-Latn-pinyin
代表的是:zh 语言文字品种,Hans 书写格局为简体中文,cmn 普通话,CN 国家和地区,Latn 变体拉丁字母,pinyin 变体拼音。
是不是感觉忽然一下这么简略的货色一下子变得高大上了。另外,zh- 这个前缀当初曾经不是举荐应用的了,zh- 当初曾经不是语言 code 了,而是 macrolang 也就是宏语言,咱们间接应用 cmn、yue(粤语)、wuu(吴语)、hsn(湘语,湖南话)这类的就能够当做 language 来应用了。因而,下面的那一段也能够这么写:
cmn-Hans-CN-Latn-pinyin
在上篇文章中,咱们讲 NumberFormatter 时说过能够间接取得中文的数字格局的输入,当初咱们想要繁体的后果呢?很简略,加上 Hant 标识书写格局为繁体中文即可。
对于语言标记规定的内容,大家能够看看文末知乎的参考链接,介绍的更为详尽。
$fmt = new NumberFormatter('zh-Hant', NumberFormatter::SPELLOUT);
echo $fmt->format(1234567.891234567890000), PHP_EOL;
// 一百二十三萬四千五百六十七點八九一二三四五六七九
获取指定语言标记规定中的各类信息
学习了语言标记的规定之后能干什么呢?Locale 类最次要的性能就在于能够剖析获取这些属性信息。
独自获取各种属性信息
echo Locale::getDisplayLanguage('cmn-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // cmn
echo Locale::getDisplayLanguage('zh-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // 中文
echo Locale::getDisplayName('cmn-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // cmn(简体,中国,LATN_PINYIN)echo Locale::getDisplayName('zh-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // 中文(简体,中国,LATN_PINYIN)echo Locale::getDisplayRegion('cmn-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // 中国
echo Locale::getDisplayRegion('zh-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // 中国
echo Locale::getDisplayScript('cmn-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // 简体中文
echo Locale::getDisplayScript('zh-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // 简体中文
echo Locale::getDisplayVariant('cmn-Hans-Latn-pinyin', 'zh_CN'), PHP_EOL; // LATN_PINYIN
echo Locale::getDisplayVariant('zh-Hans-CN-Latn-pinyin', 'zh_CN'), PHP_EOL; // LATN_PINYIN
咱们别离应用两种标记形式来测试代码,能够看到后果的比照。
- getDisplayLanguage() 办法用于获取显示的语言信息,也就是规定中的 language 内容。
- getDisplayName() 办法用于获取规范的语言名称,能够看到内容更加地丰盛。
- getDisplayRegion() 办法很显著地就是获取到了国家信息。
- getDisplayScript() 获取到的是书写格局的信息。
- getDisplayVariant() 获取到的就是变体信息
批量获取属性信息
当然,咱们也能够批量地获取到一些语言相干的信息。
$arr = Locale::parseLocale('zh-Hans-CN-Latn-pinyin');
if ($arr) {foreach ($arr as $key => $value) {echo "$key : $value", PHP_EOL;}
}
// language : zh
// script : Hans
// region : CN
// variant0 : LATN
// variant1 : PINYIN
应用 parseLocale() 办法就能获取到一个语言标记中的各类信息并保留在数组中,键为标记规定名,值为对应的内容,看看是不是和咱们下面介绍的内容是一样的。
获取所有变体信息
从下面的代码中能够看出,咱们有两个变体信息,这个也能够通过一个 getAllVariants() 办法来间接取得语言标记中的所有变体信息的数组。
$arr = Locale::getAllVariants('zh-Hans-CN-Latn-pinyin');
var_export($arr);
echo PHP_EOL;
// array (
// 0 => 'LATN',
// 1 => 'PINYIN',
// )
获取字符集相干信息
echo Locale::canonicalize('zh-Hans-CN-Latn-pinyin'), PHP_EOL; // zh_Hans_CN_LATN_PINYIN
$keywords_arr = Locale::getKeywords('zh-cn@currency=CMY;collation=UTF-8');
if ($keywords_arr) {foreach ($keywords_arr as $key => $value) {echo "$key = $value", PHP_EOL;}
}
// collation = UTF-8
// currency = CMY
canonicalize() 办法用于规范化地显示语言标记信息,能够看到它把咱们的中划线变成了下划线并且将前面的各种属性转成了大写,这就是规范化的写法。不过对于咱们的应用程序和网页来说中划线以及大小写都是反对的。当然,大家最好还是依照规范的写法来定义。
getKeywords() 用于从 @ 符号后获取语言相干的信息属性,比方咱们定义的这个 zh-cn,而后定义了它的货币为 CMY,字符集为 UTF-8,间接通过 getKeywords() 就能获取货币和字符集属性的数组。
匹配判断语言标记信息
对于语言标记来说,咱们能够判断给定的两个标记之间是否互相匹配,比方:
echo (Locale::filterMatches('cmn-CN', 'zh-CN', false)) ? "Matches" : "Does not match", PHP_EOL;
echo (Locale::filterMatches('zh-CN-Latn', 'zh-CN', false)) ? "Matches" : "Does not match", PHP_EOL;
当然,咱们也能够应用另一个 lookup() 办法来确定给定的一系列语言标记哪个与指定的标记最靠近。
$arr = [
'zh-hans',
'zh-hant',
'zh',
'zh-cn',
];
echo Locale::lookup($arr, 'zh-Hans-CN-Latn-pinyin', true, 'en_US'), PHP_EOL; // zh_hans
生成一个规范规定的语言标记
既然可能获取各类语言标记的属性信息,那么咱们能不能生成一个规范的语言标记内容呢?
$arr = [
'language' => 'en',
'script' => 'Hans',
'region' => 'CN',
'variant2' => 'rozaj',
'variant1' => 'nedis',
'private1' => 'prv1',
'private2' => 'prv2',
];
echo Locale::composeLocale($arr), PHP_EOL; // en_Hans_CN_nedis_rozaj_x_prv1_prv2
没错,composeLocale() 办法依据一个数组格局的内容,就能够生成一个残缺规范的语言标记格局内容。当然,这个测试代码是乱写的,相当于是一个 en_CN 的标记,失常不会这么写的。
acceptFromHttp 从申请头中读取语言信息
另外,Locale 类中还提供了一个从 header 头中的 Accept Language 中获取客户浏览器语言信息的办法。
// Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
echo Locale::acceptFromHttp('en_US'), PHP_EOL; // en_US
echo Locale::acceptFromHttp('en_AU'), PHP_EOL; // en_AU
echo Locale::acceptFromHttp('zh_CN'), PHP_EOL; // zh
echo Locale::acceptFromHttp('zh_TW'), PHP_EOL; // zh
不过从测试的后果来说,其实它只须要一个字符串参数就能够了,所以咱们在命令行也能够测试它。须要留神的是,对于中文来说,它不能返回区域信息,只能返回 language 信息。
总结
这个 Locale 类相干的内容其实在笔者日常的开发中根本没怎么接触过,但置信不少做跨境我的项目的同学会多少对它们会有一些理解。只能说业务接触不到,那就只能先简略地学习一下看看了,同样地,当前大家遇到相干的业务需要时,别忘了它们的存在哦!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202011/source/5.PHP 中针对区域语言标记信息的操作.php
参考文档:
https://www.php.net/manual/zh/class.locale.php
https://www.zhihu.com/question/20797118/answer/63480740
===========
各自媒体平台均可搜寻【硬核项目经理】