json_encode 使用 JSON_UNESCAPED_UNICODE

提出問題

PHP 原生的 json_encode 方法對中文進行編碼的時候,不加參數 JSON_UNESCAPED_UNICODE 獲得一串類 \uXXXX 的字符串,加參數則是咱們一般看到的中文,發生了什麼?php

確認現象

//1.php
<?php
echo json_encode('好');

# php 1.php > 1.txt

# ls -l 1.txt
-rw-r--r-- 1 root root 8 Jun 12 15:21 1.txt

# cat 1.txt
"\u597d"
//2.php
<?php
echo json_encode('好', JSON_UNESCAPED_UNICODE);

php 2.php > 2.txt

# ls -l 2.txt
-rw-r--r-- 1 root root 5 Jun 12 15:23 2.txt

# cat 2.txt
"好"

先說結論

咱們一般使用的 json 格式都是 utf-8 編碼,但它承認 utf-16 編碼的轉義。即,html

展現正常的 utf-8編碼;linux

\u597d 單個字符(有6個)拎出來傳輸的時候也都是 utf-8 編碼,但在具體解析的時候,判斷出有轉義,將\u597d這6個字符合在一塊兒,做爲utf-16編碼。json

json_encode 加參數 JSON_UNESCAPED_UNICODE,不對字符進行 utf-16 轉義,直接使用 utf-8。因爲沒有使用轉義,整個字符串大小也由8字節變小爲5字節。緣由是轉義字符 \u597d 中每一個字符佔了1字節,一共是6字節,而 utf-8編碼只有3字節,少用了3字節。segmentfault

驗證

hexdump 能夠查看文本文件以二進制格式。如下的 -c 參數,若是對應單字節有符合的 ascii 碼,會直接以 ascii 碼格式展現,不然以相應的八進制數展現;-b 參數,徹底以8進制數展現每一個字節。網絡

# hexdump -c 1.txt
0000000   "   \   u   5   9   7   d   "       
0000008

//八進制格式
# hexdump -b 1.txt
0000000 042 134 165 065 071 067 144 042       
0000008


# hexdump -c 2.txt
0000000   " 345 245 275   "         
0000005

//八進制格式
# hexdump -b 2.txt
0000000 042 345 245 275 042          
0000005
以上使用 od -w1 -b 2.txt 有同 hexdump 差很少的效果

從上面輸出不難看出, 對應的字節八進制數應該就是 345245275工具

轉換成二進制,分別是 111001011010010110111101學習

二進制還能夠轉換成16進制數,但此處有一個字節序大小端的顧慮,哪一頭開始的呢,是 275 仍是 345 對應的是開頭?網站

突破口是 對應的是3字節,3字節的 utf-8 編碼對應的開頭必定是1110(參見阮一峯的字符編碼筆記:ASCII,Unicode 和 UTF-8),正好是345的開頭,且字節內部也是大端。肯定大端後,再聯想到常說的網絡字節序是大端。看了 json標準utf-16utf-32 都有大小端的區分,惟獨 utf-8 沒有,那麼 utf-8 編碼的 json 應該就是大端的了。(也想不出若是是小端的話,多字節字符怎麼判斷的好)編碼

將二進制轉換成16進制,分別是 E5A5BD

找一個在線編碼轉換的驗證 驗證有沒有轉錯了,獲得結果:

字符 編碼10進制 編碼16進制 Unicode編碼10進制 Unicode編碼16進制
15050173 E5A5BD 22909 597D

E5A5BD 對上了。

另外一個在線的編碼轉換網站 獲得的轉換結果是 &#x597D;,這實際上 utf-8 對應的 unicode碼點,不是想要的 utf-8 編碼,嚴重誤導人,網上好些在線編碼網站都是這樣。

一些定義說明

  1. json 是一種傳輸協議,規定了一種文本組織結構,用於交互。json 經常使用 utf-8 編碼, 但不是必須。
  2. unicode 是一個標準,爲每個字符惟一對應定義一個 unicode碼點
  3. utf-8utf-16 等是針對 unicode碼點 的編碼方式。好比 utf-8 編碼對應的字節數在1-4字節,因爲短字節數量更少,因此優先分配給了越常使用的字符(unicode碼點)。

參考

相關文章
相關標籤/搜索