相信你們對 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
===========
各自媒體平臺都可搜索【硬核項目經理】