web-dev-qa-db-ja.com

PHP Unicode文字でJSONをデコードおよびエンコードする

文字を台無しにせずにデコード、変更、エンコードする必要があるjsonがあります。

JSON文字列にUnicode文字がある場合、デコードされません。 json.orgが文字列にany-Unicode-character- except-"-or-\-or- control-character。しかし、pythonでも動作しません。

{"Tag":"Odómetro"}

文字列をjson_decodeでデコードできるutf8_encodeを使用できますが、文字は別の文字に変換されます。これは、結果配列のprint_rからの結果です。 2文字。

[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 ...
33
Keyo

あなたが言ったことすべてから判断すると、あなたが扱っている元のOdómetro文字列はUTF-8ではなくISO 8859-1でエンコードされているようです。

私がそう思う理由は次のとおりです。

  • json_encodeは、ISO 8859-1からUTF-8に変換するutf8_encodeを介して入力文字列を実行した後、解析可能な出力を生成しました。
  • 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です。

したがって、UTF-8文字列を提供するようにPostgresへの接続を設定する必要があるようです。 PHPマニュアルは、接続文字列にoptions='--client_encoding=UTF8'を追加することでこれを行うことを示しています。データベースに現在保存されているデータのエンコードが間違っている可能性もあります。単純にutf8_encodeを使用できますが、これはISO 8859-1の一部である文字のみをサポートします。

最後に、別の答えが指摘したように、HTTPヘッダーなどを使用して適切な文字セットを宣言していることを確認する必要があります(もちろん、この特定の問題はprint_rテスト)。

14
John Flatness

この問題を解決する次の方法を見つけました...これがあなたのお役に立てば幸いです。

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
31
Sunny S.M

JSON_UNESCAPED_UNICODE がPHP 5.4に追加されたため、バージョンPHPを利用してアップグレードする必要があるようです。5.4はまだリリースされていませんしかし!:(

開発マシンでプレイしたい場合でも、QAには 5.4アルファリリース候補 があります。

16
Treffynnon

PHP 5.3でJSON_UNESCAPED_UNICODEを行うハックな方法。 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);
7
Keyo

ページで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'};
4
The Mask
$json = array('tag' => 'Odómetro'); // Original array
$json = json_encode($json); // {"Tag":"Od\u00f3metro"}
$json = json_decode($json); // Od\u00f3metro becomes  Odómetro
echo $json->{'tag'}; // Odómetro
echo utf8_decode($json->{'tag'}); // Odómetro

近かったので、utf8_decodeを使用してください。

4
Fernando R.

使用してみてください:

utf8_decode() and utf8_encode
3

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);

TF-8をISO 8859-1に変換する

0
Navaneeth Mohan