首頁 >後端開發 >PHP問題 >php不支援unicode是什麼意思

php不支援unicode是什麼意思

藏色散人
藏色散人原創
2021-07-27 09:35:522757瀏覽

php不支援unicode是指PHP字串不保存字元的編碼訊息,所以原生操作函數,並不知道二進位資料該如何對應文本,只能假設一個字元對應單一位元組;這樣在處理英文等ascii碼時就夠用,但對於中文等多字節字符,就會出錯。

php不支援unicode是什麼意思

本文操作環境:windows7系統、PHP7.1版,DELL G3電腦

php不支援unicode是什麼意思?為什麼說PHP不支援Unicode編碼?

#常看到有說法:PHP不支援Unicode,或是說PHP在底層不支援Unicode。雖然我知道PHP編碼很蛋疼,各種字串處理函數都非常不規範,但也還能顯示中文,一直沒搞清楚這個不支援Unicode是什麼意思。花了一些時間來梳理這方面的資訊。

先從一個例子來引入:

一個PHP腳本如下,假設檔案的編碼是UTF-8:

//文件编码UTF-8
echo strlen("中文"); // 6
echo substr("中文",0,1) // 乱码
echo substr("中文",0,3) // 中

很奇怪吧,從上面看,似乎把一個漢字當成了3個字。這就要從PHP對於字串的儲存說起了。

我總結了一下,如下:

PHP的字串,是由位元組(byte)組成的陣列構成的。也就是說,類似C語言 char a[3] = "abc" 這樣,一個字元佔據一個位元組。

除此之外,並沒有儲存文字的編碼訊息,也就是說PHP並不知道這些字串的二進位數據,應該對應怎樣的編碼。

再進一步,PHP會依照腳本檔案的編碼,來決定字串的編碼。就例如:$string = "中文";,如果腳本檔案是UTF-8,就會把中文的UTF-8的編碼:E4B8ADE69687給保存起來。

再進一步,如前說所,PHP並不保存字串的編碼資訊。所以即便中文保存為:E4B8ADE69687,在字串原生函數看來,都只是一串二進制數。所以,PHP原生字串函數只能操作單字節字元!就是把一個位元組當做一個字元來處理!

如果想明白了上面幾點,上面的程式碼例子就自然明白了:

//文件编码UTF-8
echo bin2hex("中文"); // 可以看到,"中文"对应的二进制就是:e4b8ade69687
echo strlen("中文"); // 所以按照单字节来统计长度,就是6 
echo substr("中文",0,1) // 取0到1个字节,也就是e4,并不对应某个字符的编码,所以乱码
echo substr("中文",0,3) // 取0到3个字节,刚好把`中`的编码取出来

同理,如果把檔案編碼換成GBK或別的,再實驗也會得到類似的結果,只不過GBK一個漢字佔2位元組。

那麼到現在,基本上可以明白了PHP底層不支援unicode到底說的是什麼了,總結如下:

PHP字串不保存字元的編碼訊息,所以原生操作函數,並不知道二進位資料該如何對應文本,只能【假設】一個字元對應單一位元組。這樣在處理英文等ascii碼時夠用了,但對於中文等【多字節字元】,就會出錯了。

而作為反面,我們可以看看所謂底層支援Unicode的語言的情況:

var string = "中文"
console.log(string.length); // 2
string.substr(0,1) // 中

可以看到,在JS中,能正確識別和處理多字節字符。也就是在儲存時,把文字的編碼訊息也一併儲存。 (這裡我猜測是保存的是文本的Unicode值,並不太確定,因為不了解JS的底層原理)

那麼這裡就有疑問了,PHP中如何才能正確處理多字節字元呢?答案就是mbstring擴充(具體可看:http://php.net/manual/zh/book.mbstring.php)。所謂mbstring,也就是:multi-byte string ,多位元組字串。

這套擴充功能中,有一系列與原生字串函數對應的函數,能用來正確處理多位元組字元的情況。如:strlen 對應 mb_strlen … 這些對應函數中,基本和原生函數一致,只不過通常多了一個可選參數:編碼。

舉例如下:

// 脚本类型为UTF-8
echo strlen("中文"); // 6
echo mb_strlen("中文","UTF-8"); //2  使用mb_strlen ,并传入编码 utf-8, 就会把二进制E4B8ADE69687当做utf-8的处理能正确处理
echo mb_strlen("中文"); //2  如果不传编码UTF-8,则函数会自动确定编码,文档说:如果省略,则使用内部字符编码。所以这里也当做UTF-8来处理。
echo mb_strlen("中文","GBK"); //3,如果传入编码GBK,则:e4b8ade69687会被当做gbk来处理,一个gbk字符占2字节,所以为:3

推薦學習:《PHP影片教學

以上是php不支援unicode是什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn