json_encodeでマルチバイト文字をエンコード

こんにちは。ishiBです。

先日、PHPで json_encode を使った smarty の plugin を作成する機会がありました。
そのときにマルチバイトの扱いで少しハマったので、内容を備忘録として記します。

参考)smartyとは?

下記のようなコードで配列を組み立てた後、json_encodeすることにしました。

[sourcecode language="php"]
<?php
    $title = 'タイトル'
    $json = array('title' => $title,
                  'body'  => 'test');
    echo json_encode($json);
?>
[/sourcecode]

としたところ、期待していた結果は、

[sourcecode language="php"]
{"title":"タイトル","body":"test"}
[/sourcecode]

だったんですが、

[sourcecode language="php"]
{"title":null,"body":"test"}
[/sourcecode]

という結果になってしまいました。

これは、phpのコードがeuc-jpで記述されていたことが原因で、
PHPマニュアルを確認すると、「すべての文字列データは、UTF-8 エンコードされたいなければいけません。」とありました。

そこで下記のように修正しました。

[sourcecode language="php"]
<?php
    $title = 'タイトル'
    $json = array('title' => mb_convert_encoding($title, "UTF-8", "EUC-JP"),
                  'body'  => 'test');
    $json = mb_convert_encoding($json, "EUC-JP", "UTF-8")
    json_encode($json);
?>
[/sourcecode]

そうすると今度は

[sourcecode language="php"]
{"title":"\u30BF\u30A4\u30C8\u30EB","body":"test"}
[/sourcecode]

という結果になってしまいました。

どうやらマルチバイトをエスケープしないようにするには第二引数に JSON_UNESCAPED_UNICODE を指定する必要があるようです。

※このオプションはPHP5.4から追加されています。
PHP5.4以前のバージョンではhex2binなどを使いもう一手間かける必要があります。

[sourcecode language="php"]
<?php
    $title = 'タイトル'
    $json = array('title' =--> mb_convert_encoding($title, "UTF-8", "EUC-JP"),
                  'body'  => 'test');
    $json = mb_convert_encoding($json, "EUC-JP", "UTF-8")
    json_encode($json);
?>
[/sourcecode]

とすることで、やっと期待していた通りの結果が得られました。

同じような事象に遭遇している方などの参考になれば幸いです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です