当使用“特殊” Unicode字符时,当编码为JSON时,它们作为奇怪的垃圾出现:
php > echo json_encode(['foo' => '馬']); {"foo":"\u99ac"}
为什么?我的编码做错了吗?
(这是一劳永逸地澄清该主题的参考问题,因为这是一遍又一遍的。)
首先: 这里没有错。 这就是 可以 在JSON中编码字符的 方式 。它是官方 标准。它基于如何在 Javascript ECMAScript(第7.8.4节“字符串文字”)中形成字符串文字的方式,其描述如下:
任何代码点都可以表示为十六进制数。此数字的含义由ISO / IEC 10646确定。如果代码点位于基本多语言平面(U + 0000至U + FFFF)中,则可以将其表示为六个字符的序列:反向固线,后跟小写字母u,然后是对代码点进行编码的四个十六进制数字。[…]例如,仅包含单个反斜线字符的字符串可以表示为“ \ u005C”。
简而言之:任何字符都可以编码为\u....,其中....字符的Unicode代码点(对于BMP之外的字符,则为UTF-16代理对的一半的代码点)。
\u....
....
"馬" "\u99ac"
这两个字符串文字代表完全相同的字符,它们是绝对等价的。当这些字符串文字由兼容的JSON解析器解析时,它们都将产生字符串“马”。它们 看起来 并不相同,但是它们在JSON数据编码格式中的 含义 相同。
PHP json_encode最好使用\u....转义序列对非ASCII字符进行编码。从技术上讲,它不是必须的,但确实如此。结果是完全正确的。如果您希望在JSON中使用文字字符而不是转义序列,则可以JSON_UNESCAPED_UNICODE在PHP 5.4或更高版本中设置标志:
json_encode
JSON_UNESCAPED_UNICODE
php > echo json_encode(['foo' => '馬'], JSON_UNESCAPED_UNICODE); {"foo":"馬"}
需要强调的是:这只是一个 首选项 ,以任何方式都不需要在JSON中传输“ Unicode字符”。