PHP json_decode的UTF-8问题

时间:2014-03-19 17:27:27

标签: php json perl encoding utf-8

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。

我设法用几行PH​​P(5.3.24)重现了我所看到的内容:

<?php
$val = array("Millán");
print json_encode($val)."\n";

根据the PHP documentationstring 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输入,所以我对它的工作原理有点困惑。

2 个答案:

答案 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