UTF-8 issue with PHP's json_decode


UTF-8 issue with PHP's json_decode

EDIT2:问题在于我的Perl客户端如何解释PHP json_encode的输出,默认情况下输出Unicode代码点。将JSON Perl模块置于ascii模式(my $j = JSON->new()->ascii();(使事情按预期工作。


我正在使用用Perl编写的客户端与用PHP编写的返回JSON的API进行交互,然后将JSON的修改版本提交回同一API。该 API 从编码为 UTF8 的 PostgreSQL 数据库中提取值。我遇到的是 API 返回不同的字符编码,即使 PHP 从数据库接收的值是正确的 UTF-8。

我已经设法用几行 PHP (5.3.24( 重现了我所看到的内容:

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

根据 PHP 文档,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 已更改为 "Unicode" 小写 a-acute json_encode

如何防止 PHP/json_encode切换此变量的编码?

编辑:有趣的是,如果我将字符串文字更改为utf8_encode("Millán")那么事情就会按预期工作。utf8_encode文档说该功能仅支持 ISO-8859-1 输入,所以我对为什么有效有点困惑。

这完全是基于误解。 json_encode将非 ASCII 字符编码为 Unicode 转义序列'u....。这些序列不引用任何 UTF 编码中的任何物理字节编码,它通过其 Unicode 码位引用字符。U+00E1 是字符 á 的 Unicode 码位。任何正确的 JSON 解析器都会将'u00e1解码回字符"á"。这里没有问题。

请尝试以下命令来解决他们的问题。

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

注意:将JSON_UNESCAPED_UNICODE参数添加到json_encode函数中以保留原始值。

对于 python,这个 将 json.dumps 中的 utf-8 文本保存为 UTF8,而不是 ''u 转义序列