一尘不染

PHP用Unicode字符解码和编码json

php

我有一些json,我需要解码,更改然后编码,而不会弄乱任何字符。

如果我在json字符串中包含unicode字符,它将无法解码。我不知道为什么,因为json.org说一个字符串可以包含:any-Unicode- character- except-"-or-\-or- control-character。但这在python中也不起作用。

{"Tag":"Odómetro"}

我可以使用utf8_encode,该字符串将允许使用json_decode对字符串进行解码,但是字符会被压缩成其他形式。这是来自结果数组的print_r的结果。两个字符。

[Tag] => Odómetro

当我再次对数组编码时,字符转义为ascii,根据json规范是正确的:

"Tag"=>"Od\u00f3metro"

有什么办法可以使我逃脱吗?json_encode没有提供此类选项,utf8_encode似乎也不起作用。

编辑 我看到json_encode有一个unescaped_unicode选项。但是,它没有按预期工作。哦,该死,它仅在php
5.4上。我只能使用一些正则表达式,因为我只有5.3。

$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...

阅读 273

收藏
2020-05-29

共1个答案

一尘不染

从您所说的一切来看,Odómetro您要处理的原始字符串似乎是使用ISO 8859-1(而不是UTF-8)编码的。

这就是我这么认为的原因:

  • json_encode通过运行输入字符串后产生了可分析的输出,该字符串utf8_encode从ISO 8859-1转换为UTF-8。
  • 您确实说过,使用print_r完后使用时会得到“混乱的”输出utf8_encode,但是实际上得到的输出经过拼凑的正是通过尝试将UTF-8文本解析为ISO 8859-1会发生的情况(ó \x63\xb3在UTF-8中,但是序列ó符合ISO 8859-1。
  • 您的htmlentities骇客解决方案有效。htmlentities需要知道输入字符串的编码是什么才能正常工作。如果未指定,则假定为ISO 8859-1。(html_entity_decode,令人困惑的是,默认值为UTF-8,因此您的方法具有将ISO 8859-1转换为UTF-8的效果。)
  • 您说过您在Python中有同样的问题,这似乎使PHP成为问题。

PHP将使用\uXXXX转义,但是正如您所指出的,这是有效的JSON。

因此,似乎您需要配置与Postgres的连接,以便为您提供UTF-8字符串。PHP手册指示您可以通过将其附加options='-- client_encoding=UTF8'到连接字符串来完成此操作。当前存储在数据库中的数据也可能使用错误的编码。(您可以简单地使用utf8_encode,但这仅支持ISO
8859-1的字符)。

最后,作为另一个答案,您需要确保使用HTTP标头或其他方式声明正确的字符集(当然,此特定问题可能只是您print_r进行测试的环境的产物) 。

2020-05-29