首頁  >  文章  >  後端開發  >  淺談PHP中如何操作區域語言標記訊息?

淺談PHP中如何操作區域語言標記訊息?

青灯夜游
青灯夜游轉載
2021-09-09 19:53:263366瀏覽

PHP中如何針對區域語言標記資訊進行操作?以下這篇文章為大家介紹一下PHP中針對區域語言標記資訊的操作,希望對大家有幫助!

淺談PHP中如何操作區域語言標記訊息?

相信大家對 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

推荐学习:《PHP视频教程

以上是淺談PHP中如何操作區域語言標記訊息?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除