// # echo $LANG;// en_US.UTF-8// php.ini// intl.default_locale => no value => no valueecho Locale::getDefault(), PHP_EOL; // en_US_POSIXini_set(39;intl.default_locale', 'zh_CN');echo Locale::getDefault(), PHP_EOL; // zh_CNLocale::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; // cmnecho 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_PINYINecho 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_USecho Locale::acceptFromHttp('en_AU'), PHP_EOL; // en_AUecho Locale::acceptFromHttp('zh_CN'), PHP_EOL; // zhecho 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