相信大家對 zh_CN 這個(gè)東西絕對不會(huì)陌生,不管是 PHP 中,還是在我們的網(wǎng)頁上,都會(huì)見到它的身影。其實(shí)這就是指定我們的顯示編碼是什么國家或者地區(qū)的,使用何種語言。對于這種區(qū)域語言的標(biāo)記來說,PHP 中也有很多好玩的內(nèi)容。今天,我們要學(xué)習(xí)的 Locale 類就是操作區(qū)域語言相關(guān)內(nèi)容的,它無法被實(shí)例化,所有全部功能方法都是靜態(tài)的。
獲取及設(shè)置當(dāng)前的區(qū)域語言信息
首先就是我們可以動(dòng)態(tài)地獲取和設(shè)置相應(yīng)的區(qū)域語言信息。
1
2
3
4
5
6
7
8
9
10
11
|
// # 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 |
默認(rèn)情況下,使用 getDefault() 方法獲得的是 php.ini 文件中的 intl.default_locale 配置的內(nèi)容。如果在 php.ini 中也沒有配置的話,就會(huì)取操作系統(tǒng)的 $LANG 值里面的內(nèi)容,也就是我們上面例子中輸出的 en_US_POSIX ,POSIX 表示的就是來自操作系統(tǒng)的配置。
使用 ini_set() 直接修改 ini 的配置或者使用 setDefault() 方法都是可以動(dòng)態(tài)地修改當(dāng)前的區(qū)域語言設(shè)置的。
關(guān)于語言標(biāo)記的規(guī)則
在繼續(xù)學(xué)習(xí)下面的內(nèi)容之前,我們先來學(xué)習(xí)一下語言標(biāo)記的規(guī)范。對于大多數(shù)人來說,可能只接觸過 en_US 、 zh_CN 這類的標(biāo)記,但其實(shí)它的完整定義是很長的,只是我們使用這種簡寫的方式時(shí),很多內(nèi)容會(huì)以默認(rèn)的形式提供。完整的標(biāo)記規(guī)則是:
language-extlang-script-region-variant-extension-privateuse
語言文字種類-擴(kuò)展語言文字種類-書寫格式-國家和地區(qū)-變體-擴(kuò)展-私有
也就是說,我們的 zh_CN 可以這樣寫:
zh-cmn-Hans-CN-Latn-pinyin
代表的是:zh 語言文字種類,Hans 書寫格式為簡體中文,cmn 普通話,CN 國家和地區(qū),Latn 變體拉丁字母,pinyin 變體拼音。
是不是感覺突然一下這么簡單的東西一下子變得高大上了。另外,zh- 這個(gè)前綴現(xiàn)在已經(jīng)不是推薦使用的了,zh- 現(xiàn)在已經(jīng)不是語言 code 了,而是 macrolang 也就是宏語言,我們直接使用 cmn 、 yue(粵語)、wuu(吳語)、hsn(湘語,湖南話)這類的就可以當(dāng)做 language 來使用了。因此,上面的那一段也可以這么寫:
cmn-Hans-CN-Latn-pinyin
在上篇文章中,我們講 NumberFormatter 時(shí)說過可以直接獲得中文的數(shù)字格式的輸出,現(xiàn)在我們想要繁體的結(jié)果呢?很簡單,加上 Hant 標(biāo)識(shí)書寫格式為繁體中文即可。
關(guān)于語言標(biāo)記規(guī)則的內(nèi)容,大家可以看看文末知乎的參考鏈接,介紹的更為詳盡。
1
2
3
|
$fmt = new NumberFormatter( 'zh-Hant' , NumberFormatter::SPELLOUT); echo $fmt ->format(1234567.891234567890000), PHP_EOL; // 一百二十三萬四千五百六十七點(diǎn)八九一二三四五六七九 |
獲取指定語言標(biāo)記規(guī)則中的各類信息
學(xué)習(xí)了語言標(biāo)記的規(guī)則之后能干什么呢?Locale 類最主要的功能就在于可以分析獲取這些屬性信息。
單獨(dú)獲取各種屬性信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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 |
我們分別使用兩種標(biāo)記方式來測試代碼,可以看到結(jié)果的對比。
- getDisplayLanguage() 方法用于獲取顯示的語言信息,也就是規(guī)則中的 language 內(nèi)容。
- getDisplayName() 方法用于獲取標(biāo)準(zhǔn)的語言名稱,可以看到內(nèi)容更加地豐富。
- getDisplayRegion() 方法很明顯地就是獲取到了國家信息。
- getDisplayScript() 獲取到的是書寫格式的信息。
- getDisplayVariant() 獲取到的就是變體信息
批量獲取屬性信息
當(dāng)然,我們也可以批量地獲取到一些語言相關(guān)的信息。
1
2
3
4
5
6
7
8
9
10
11
|
$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() 方法就能獲取到一個(gè)語言標(biāo)記中的各類信息并保存在數(shù)組中,鍵為標(biāo)記規(guī)則名,值為對應(yīng)的內(nèi)容,看看是不是和我們上面介紹的內(nèi)容是一樣的。
獲取所有變體信息
從上面的代碼中可以看出,我們有兩個(gè)變體信息,這個(gè)也可以通過一個(gè) getAllVariants() 方法來直接獲得語言標(biāo)記中的所有變體信息的數(shù)組。
1
2
3
4
5
6
7
|
$arr = Locale::getAllVariants( 'zh-Hans-CN-Latn-pinyin' ); var_export( $arr ); echo PHP_EOL; // array ( // 0 => 'LATN', // 1 => 'PINYIN', // ) |
獲取字符集相關(guān)信息
1
2
3
4
5
6
7
8
9
10
|
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() 方法用于規(guī)范化地顯示語言標(biāo)記信息,可以看到它把我們的中劃線變成了下劃線并且將后面的各種屬性轉(zhuǎn)成了大寫,這就是規(guī)范化的寫法。不過對于我們的應(yīng)用程序和網(wǎng)頁來說中劃線以及大小寫都是支持的。當(dāng)然,大家最好還是按照標(biāo)準(zhǔn)的寫法來定義。
getKeywords() 用于從 @ 符號(hào)后獲取語言相關(guān)的信息屬性,比如我們定義的這個(gè) zh-cn ,然后定義了它的貨幣為 CMY ,字符集為 UTF-8 ,直接通過 getKeywords() 就能獲取貨幣和字符集屬性的數(shù)組。
匹配判斷語言標(biāo)記信息
對于語言標(biāo)記來說,我們可以判斷給定的兩個(gè)標(biāo)記之間是否相互匹配,比如:
1
2
|
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; |
當(dāng)然,我們也可以使用另一個(gè) lookup() 方法來確定給定的一系列語言標(biāo)記哪個(gè)與指定的標(biāo)記最接近。
1
2
3
4
5
6
7
|
$arr = [ 'zh-hans' , 'zh-hant' , 'zh' , 'zh-cn' , ]; echo Locale::lookup( $arr , 'zh-Hans-CN-Latn-pinyin' , true, 'en_US' ), PHP_EOL; // zh_hans |
生成一個(gè)標(biāo)準(zhǔn)規(guī)則的語言標(biāo)記
既然能夠獲取各類語言標(biāo)記的屬性信息,那么我們能不能生成一個(gè)標(biāo)準(zhǔn)的語言標(biāo)記內(nèi)容呢?
1
2
3
4
5
6
7
8
9
10
|
$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 |
沒錯(cuò),composeLocale() 方法根據(jù)一個(gè)數(shù)組格式的內(nèi)容,就可以生成一個(gè)完整標(biāo)準(zhǔn)的語言標(biāo)記格式內(nèi)容。當(dāng)然,這個(gè)測試代碼是亂寫的,相當(dāng)于是一個(gè) en_CN 的標(biāo)記,正常不會(huì)這么寫的。
acceptFromHttp 從請求頭中讀取語言信息
另外,Locale 類中還提供了一個(gè)從 header 頭中的 Accept Language 中獲取客戶瀏覽器語言信息的方法。
1
2
3
4
5
6
7
|
// 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 |
不過從測試的結(jié)果來說,其實(shí)它只需要一個(gè)字符串參數(shù)就可以了,所以我們在命令行也可以測試它。需要注意的是,對于中文來說,它不能返回區(qū)域信息,只能返回 language 信息。
總結(jié)
這個(gè) Locale 類相關(guān)的內(nèi)容其實(shí)在筆者日常的開發(fā)中基本沒怎么接觸過,但相信不少做跨境項(xiàng)目的同學(xué)應(yīng)該多少對它們會(huì)有一些了解。只能說業(yè)務(wù)接觸不到,那就只能先簡單地學(xué)習(xí)一下看看了,同樣地,以后大家遇到相關(guān)的業(yè)務(wù)需求時(shí),別忘了它們的存在哦!
測試代碼:
參考文檔:
https://www.php.net/manual/zh/class.locale.php
https://www.zhihu.com/question/20797118/answer/63480740
到此這篇關(guān)于PHP中針對區(qū)域語言標(biāo)記信息的操作的文章就介紹到這了,更多相關(guān)PHP區(qū)域語言標(biāo)記信息內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://www.cnblogs.com/zyblog-coder/archive/2021/07/01/14957238.html