参考:为什么我的"特别"使用json_encode编码奇怪的Unicode字符?

时间:2014-03-30 15:12:13

标签: php unicode utf-8 json

使用"特殊" Unicode字符在编码为JSON时出现奇怪的垃圾:

php > echo json_encode(['foo' => '馬']);
{"foo":"\u99ac"}

为什么呢?我的编码错了吗?

(这是一个一劳永逸地澄清主题的参考问题,因为这一次又一次出现。)

1 个答案:

答案 0 :(得分:21)

首先:这里没有任何问题。这就是可以以JSON编码的方式。它位于the official standard。它基于如何在 Javascript ECMAScript(section 7.8.4 "String Literals")中形成字符串文字,并且描述如下:

  

任何代码点都可以表示为十六进制数。这种数字的含义由ISO / IEC 10646确定。如果代码点在基本多语言平面(U + 0000到U + FFFF)中,那么它可以表示为六个字符的序列:反向固相,后跟小写字母u,后跟四个编码代码点的十六进制数字。 [...]因此,例如,只包含一个反向固相字符的字符串可以表示为“\ u005C”。

简而言之:任何字符都可以编码为\u....,其中....是字符的Unicode代码点(或者UTF-16代理对的一半的代码点,对于外部字符BMP)。

"馬"
"\u99ac"

这两个字符串文字代表完全相同的字符,它们绝对相同。当这些字符串文字由兼容的JSON解析器解析时,它们都将产生字符串“马”。它们看起来相同,但它们意味着在JSON数据编码格式中是相同的。

PHP的json_encode最好使用\u....转义序列对非ASCII字符进行编码。从技术上讲,它没有,但确实如此。结果完全有效。如果您希望在JSON中使用文字字符而不是转义序列,则可以在PHP 5.4或更高版本中设置JSON_UNESCAPED_UNICODE标志:

php > echo json_encode(['foo' => '馬'], JSON_UNESCAPED_UNICODE);
{"foo":"馬"}

要强调:这只是首选项,无需以任何方式在JSON中传输“Unicode字符”。