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

时间:2011-09-11 23:09:44

标签: php json unicode character-encoding

我有一些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 ...

8 个答案:

答案 0 :(得分:28)

我找到了解决此问题的以下方法......我希望这可以帮助您。

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);

答案 1 :(得分:16)

在PHP 5.4中添加了

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

如果您想在开发机器上玩游戏,QA上有5.4 alpha release candidate

答案 2 :(得分:14)

从你所说的一切来看,你所处理的原始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(ó在UTF-8中为\x63\xb3,但在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测试。

答案 3 :(得分: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);

答案 4 :(得分:4)

尝试在页面中设置utf-8编码:

header('content-type:text/html;charset=utf-8');

这对我有用:

$arr = array('tag' => 'Odómetro');
$encoded = json_encode($arr);
$decoded = json_decode($encoded);
echo $decoded->{'tag'};

答案 5 :(得分:3)

尝试使用:

utf8_decode() and utf8_encode

答案 6 :(得分:3)

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
  <div ng-controller="SomeCtrl">
    <div ng-repeat="toto in [1,2,4,5]">
      <input ng-model="something" />
      <input ng-model="something" />
      <button ng-click="modify()">Modify</button>
    </div>
  </div>

</div>

You were close, just use utf8_decode.

答案 7 :(得分:0)

要对包含特殊字符的数组进行编码,请使用ISO 8859-1至UTF8。 (如果utf8_encode和utf8_decode不适用于您,则可以选择)

ISO-8859-1中的所有内容都应转换为UTF8:

$utf8 = utf8_encode('이 감사의 마음을 전합니다!'); //contains UTF8 & ISO 8859-1 characters;    
$iso88591 = mb_convert_encoding($utf8, 'ISO-8859-1', 'UTF-8');
$data = $iso88591;

编码应在此之后工作:

$encoded_data = json_encode($data);

Convert UTF-8 to & from ISO 8859-1