Php 参考:为什么我的;特别";使用json编码的Unicode字符?

Php 参考:为什么我的;特别";使用json编码的Unicode字符?,php,unicode,utf-8,json,Php,Unicode,Utf 8,Json,当使用“特殊”Unicode字符时,当编码为JSON时,它们会变成奇怪的垃圾: php > echo json_encode(['foo' => '馬']); {"foo":"\u99ac"} 为什么??我的编码有问题吗 (这是一个可以一劳永逸地澄清主题的参考问题,因为这个问题会反复出现。)首先:这里没有错。这就是用JSON编码字符的方式。它在里面。它基于Javascript ECMAScript()中字符串文字的形成方式,描述如下: 任何代码点都可以表示为十六进制数。该数字的含义

当使用“特殊”Unicode字符时,当编码为JSON时,它们会变成奇怪的垃圾:

php > echo json_encode(['foo' => '馬']);
{"foo":"\u99ac"}
为什么??我的编码有问题吗


(这是一个可以一劳永逸地澄清主题的参考问题,因为这个问题会反复出现。)

首先:这里没有错。这就是用JSON编码字符的方式。它在里面。它基于Javascript ECMAScript()中字符串文字的形成方式,描述如下:

任何代码点都可以表示为十六进制数。该数字的含义由ISO/IEC 10646确定。如果代码点位于基本多语言平面(U+0000到U+FFFF)中,则它可以表示为六个字符的序列:一个反向索利多卡因,后跟小写字母U,后跟编码代码点的四个十六进制数字。[…]因此,例如,仅包含单个反向索利多士字符的字符串可以表示为“\u005C”

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

这两个字符串文字表示完全相同的字符,它们是绝对等效的。当这些字符串文本由兼容的JSON解析器解析时,它们都将生成字符串“馬". 它们看起来不一样,但在JSON数据编码格式中的含义是相同的

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

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

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

注意:JSON是,而不是ecma 262(javascript)。非BMP Unicode代码点也可以表示为UTF-16代理项对,例如is
“\ud83d\udc93“
作为json字符串。+1。除此之外,JSON只支持少数和所谓的JSON。如果您使用的是来自ECMAscript以外的语言的JSON,更好的参考可能是RFC 7159(),它与ECMA-404对齐。
php > echo json_encode(['foo' => '馬'], JSON_UNESCAPED_UNICODE);
{"foo":"馬"}