EDIT2 :问题在于我的Perl客户端如何解释默认输出Unicode代码点的PHP json_encode
的输出。将JSON
Perl模块置于ascii模式(my $j = JSON->new()->ascii();
)使得事情按预期工作。
我正在使用用Perl编写的客户端与PHP编写的API进行交互,该API使用Perl编写的客户端返回JSON,然后将修改后的JSON版本提交回相同的API。 API从编码为UTF8的PostgreSQL数据库中提取值。我正在运行的是API返回不同的字符编码,即使PHP从数据库收到的值是正确的UTF-8。
我设法用几行PHP(5.3.24)重现了我所看到的内容:
<?php
$val = array("Millán");
print json_encode($val)."\n";
根据the PHP documentation,string literals are encoded ... in whatever fashion [they are] encoded in the script file
。
这是十六进制转储文件编码(UTF-8小写a-acute = c3 a1):
$ grep ill test.php | od -An -t x1c
24 76 61 6c 20 3d 20 61 72 72 61 79 28 22 4d 69
$ v a l = a r r a y ( " M i
6c 6c c3 a1 6e 22 29 3b 0a
l l 303 241 n " ) ; \n
以下是PHP的输出:
$ php -f test.php | od -An -t x1c
5b 22 4d 69 6c 6c 5c 75 30 30 65 31 6e 22 5d 0a
[ " M i l l \ u 0 0 e 1 n " ] \n
UTF-8小写字母a-acute已由json_encode
更改为"Unicode" lower case a-acute。
如何让PHP / json_encode
不要切换此变量的编码?
编辑:有趣的是,如果我将字符串文字更改为utf8_encode("Millán")
,那么事情就会按预期工作。 utf8_encode
文档说该函数仅支持ISO-8859-1输入,所以我对它的工作原理有点困惑。
答案 0 :(得分:1)
这完全基于误解。 json_encode
将非ASCII字符编码为Unicode转义序列\u....
。这些序列在任何UTF编码中都不引用任何物理字节编码,它通过Unicode代码点引用该字符。 U + 00E1是字符á
的Unicode代码点。任何正确的JSON解析器都会将\u00e1
解码回字符“á”。这里没有问题。
答案 1 :(得分:0)
尝试以下命令来解决他们的问题。
<?php
$val = array("Millán");
print json_encode($val, JSON_UNESCAPED_UNICODE);
注意:将 JSON_UNESCAPED_UNICODE 参数添加到json_encode函数以保留原始值。
对于python,这是Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence