使用"特殊" Unicode字符在编码为JSON时出现奇怪的垃圾:
php > echo json_encode(['foo' => '馬']);
{"foo":"\u99ac"}
为什么呢?我的编码错了吗?
(这是一个一劳永逸地澄清主题的参考问题,因为这一次又一次出现。)
答案 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字符”。