題の通り7.2 より前のバージョンの PHP では is_object に object を渡しても false になる場合があります。私的にこれは直感的でない挙動で、他の多くの方もそう思ったのか PHP 7.2 以降でこの動作はなくなりました。
これが起きる例は次です。
<?php // あるクラスをシリアライズ class Hoge { } $a = new Hoge(); echo serialize($a);// O:4:"Hoge":0:{} var_dump(is_object($a));// bool(true)
<?php // シリアライズ元がないクラスでアンシリアライズ $b = unserialize('O:4:"Hoge":0:{}'); var_dump($b); //object(__PHP_Incomplete_Class)#1 (1) { // ["__PHP_Incomplete_Class_Name"]=> // string(4) "Hoge" //} var_dump(is_object($b)); // if(PHPのバージョン >= 7.2.0) { // bool(true) // } else { // bool(false) // }
Online PHP editor | output for LTdrs
シリアライズ元はobjectであり、アンシリアライズ後もクラス未定義によるクラスのインスタンスですがobjectです。しかし、is_object関数にかけるとfalseになります。このため、PHP 7.1以前のバージョンでオブジェクトか否かを7.2以降的、言い換えれば直感的に識別するならば次の様にするべきです。
<?php /** * PHP 7.2.0 以降の is_object の挙動をする関数 * @param mixed $value 検証対象の値 * @return bool */ function is_object_like_72($value) { return is_object($value) || $value instanceof __PHP_Incomplete_Class; } $b = unserialize('O:4:"Hoge":0:{}'); var_dump($b); /* object(__PHP_Incomplete_Class)#1 (1) { ["__PHP_Incomplete_Class_Name"]=> string(4) "Hoge" } */ var_dump(is_object($b));// false var_dump(is_object_like_72($b));// true
is_object に加えて特例も判定するのみです。
この is_object に object を渡しても false になる挙動が現れる PHP バージョンは既にサポート終了ですが、やんごとなき理由で触らなければいけない時は多々あります。またこれはオートローダや適切なロード先を読み込む前に片っ端からアンシリアライズする様な処理で引っ掛かりやすいです。そういったものがあると頭の片隅に入れておくと役に立つかもしれません。
ちなみに PHP の公式ドキュメントにはしっかり記載があります。
PHP: is_object – Manual
バージョン 説明 7.2.0 クラス定義が存在せず (__PHP_Incomplete_Class クラス)、
かつシリアライズ化されていないオブジェクトに対して、
is_object() 関数はtrue
を返すようになりました。
これより前のバージョンでは、false
を返していました。