PHP解码和编码带有unicode字符的json

Key*_*eyo 36 php unicode json character-encoding

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

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

{"Tag":"Odómetro"}
Run Code Online (Sandbox Code Playgroud)

我可以使用utf8_encode,它将允许使用json_decode对字符串进行解码,但是该字符会被破坏成其他内容.这是结果数组的print_r的结果.两个字符.

[Tag] => Odómetro
Run Code Online (Sandbox Code Playgroud)

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

"Tag"=>"Od\u00f3metro"
Run Code Online (Sandbox Code Playgroud)

有什么方法可以解除这个吗?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 ...
Run Code Online (Sandbox Code Playgroud)

Sun*_*S.M 37

我找到了以下方法来解决这个问题...我希望这可以帮到你.

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
Run Code Online (Sandbox Code Playgroud)


Tre*_*non 17

JSON_UNESCAPED_UNICODE在PHP 5.4中添加,因此看起来您需要升级您的PHP版本才能利用它.5.4虽然尚未发布!:(

如果你想在你的开发机器上玩,那么在QA上有一个5.4 alpha版本候选版本.


Joh*_*ess 15

从你所说的一切来看,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\xb3UTF-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进行测试的环境的工件) .


Key*_*eyo 7

在PHP 5.3中执行JSON_UNESCAPED_UNICODE的一种hacky方式.对PHP json支持感到非常失望.也许这会帮助别人.

$array = some_json();
// Encode all string children in the array to html entities.
array_walk_recursive($array, function(&$item, $key) {
    if(is_string($item)) {
        $item = htmlentities($item);
    }
});
$json = json_encode($array);

// Decode the html entities and end up with unicode again.
$json = html_entity_decode($rson);
Run Code Online (Sandbox Code Playgroud)

  • 如果`$ array`中的字符串是(并且我讨厌不断敲打同一个鼓)用ISO 8859-1编码,这只能可靠地工作.实际上,这是一种从ISO 8859-1转换为UTF-8的复杂方式.这**会产生没有Unicode转义序列的JSON效果,但是如果你的输入字符串是UTF-8,你*需要*将`'UTF-8'`作为charset参数传递给`htmlentities`上班. (5认同)

小智 7

$json = array(\'tag\' => \'Od\xc3\xb3metro\'); // Original array\n$json = json_encode($json); // {"Tag":"Od\\u00f3metro"}\n$json = json_decode($json); // Od\\u00f3metro becomes  Od\xc3\x83\xc2\xb3metro\necho $json->{\'tag\'}; // Od\xc3\x83\xc2\xb3metro\necho utf8_decode($json->{\'tag\'}); // Od\xc3\xb3metro\n
Run Code Online (Sandbox Code Playgroud)\n\n

你很接近,只需使用 utf8_decode 即可。

\n