相信你们对 zh_CN 这个东西绝对不会陌生,不论是 PHP 中,仍是在咱们的网页上,都会见到它的身影。其实这就是指定咱们的显示编码是什么国家或者地区的,使用何种语言。对于这种区域语言的标记来讲,PHP 中也有不少好玩的内容。今天,咱们要学习的 Locale 类就是操做区域语言相关内容的,它没法被实例化,全部所有功能方法都是静态的。php
首先就是咱们能够动态地获取和设置相应的区域语言信息。git
// # 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 表示的就是来自操做系统的配置。github
使用 ini_set() 直接修改 ini 的配置或者使用 setDefault() 方法都是能够动态地修改当前的区域语言设置的。segmentfault
在继续学习下面的内容以前,咱们先来学习一下语言标记的规范。对于大多数人来讲,可能只接触过 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 标识书写格式为繁体中文便可。编码
关于语言标记规则的内容,你们能够看看文末知乎的参考连接,介绍的更为详尽。url
$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
咱们分别使用两种标记方式来测试代码,能够看到结果的对比。
固然,咱们也能够批量地获取到一些语言相关的信息。
$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 的标记,正常不会这么写的。
另外,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
===========
各自媒体平台都可搜索【硬核项目经理】