[PHP] json_decode と unserialze それぞれエラーになった時の挙動の比較

ITPHP

json_decode と unserilze でそれぞれ複合がエラーになった際の挙動についてのメモです。

検証環境: PHP 7.3.6

まず出力結果ですが、公式ドキュメントにある通り、下記の結果になります。

json_decode : null
unserialze : falseを返し、PHP Noticeが発生

unserialize : https://www.php.net/manual/ja/function.unserialize.php

json_decode : https://www.php.net/manual/ja/function.json-decode.php

以下それぞれの挙動を検証してみたコードです。

処理内容

json_encode、もしくは serialize した変数をbase64で暗号化します。

暗号化された変数に文字列を挿入し、base64で複合し、json_encode、もしくは serialize します。

json_decodeがエラーになるサンプルコード

<?php 

$param = array(
    "Apple" => array(
        "color" => "red"
    )
);

$encodedParam = base64_encode(json_encode($param));

var_dump($encodedParam);

$hackedParam = substr_replace($encodedParam, "XYZ", 5, 0);

var_dump($hackedParam);

$decodedParam = json_decode(base64_decode($hackedParam));

var_dump($decodedParam);

出力結果:

string(36) "eyJBcHBsZSI6eyJjb2xvciI6InJlZCJ9fQ=="
string(39) "eyJBcXYZHBsZSI6eyJjb2xvciI6InJlZCJ9fQ=="
NULL

NULLが返ってきてますね。

続いて、unserialize です。

unserializeがエラーになるサンプルコード

<?php

$param = array(
    "Apple" => array(
        "color" => "red"
    )
);

$encodedParam = base64_encode(serialize($param));

var_dump($encodedParam);

$hackedParam = substr_replace($encodedParam, "XYZ", 5, 0);

var_dump($hackedParam);

$decodedParam = unserialize(base64_decode($hackedParam));

var_dump($decodedParam);

出力結果:

PHP Notice:  unserialize(): Error at offset 0 of 48 bytes in

E_NOTICEが発生しました。

これではfalseが返ってきてるか確認できないので、エラーハンドラを追記します。

unserializeがエラーになるサンプルコード(エラーハンドラ付き)

<?php

function errorHandler($errno, $errstr, $errfile, $errline)
{
    if($errno === E_NOTICE) {
        echo 'E_NOTICE(発生)';
    }
}

set_error_handler('errorHandler');

$param = array(
    "Apple" => array(
        "color" => "red"
    )
);

$encodedParam = base64_encode(serialize($param));

var_dump($encodedParam);

$hackedParam = substr_replace($encodedParam, "XYZ", 5, 0);

var_dump($hackedParam);


$decodedParam = unserialize(base64_decode($hackedParam));

var_dump($decodedParam);

出力結果:

string(64) "YToxOntzOjU6IkFwcGxlIjthOjE6e3M6NToiY29sb3IiO3M6MzoicmVkIjt9fQ=="
string(67) "YToxOXYZntzOjU6IkFwcGxlIjthOjE6e3M6NToiY29sb3IiO3M6MzoicmVkIjt9fQ=="
E_NOTICE(発生)bool(false)

E_NOTICEが発生し、falseが返ってきました。

json_decode と unserilze でそれぞれエラーになった際の挙動について確認してきました。

json_decode は null になり、unserilze は false が返ってきて、E_NOTICE が発生します。

それぞれ違いを意識して、実装していく必要がありますね。

以上になります。

スポンサーリンク

Posted by nobuhiro harada