When unserializing an object whose class definition is not present, PHP returns an instance of the special type, __PHP_Incomplete_Class
, which issues notices if you attempt to call a method or access a property.
For example, this code produces the following:
andrew@fake:~$ php incomplete.php
object(__PHP_Incomplete_Class)#1 (2) {
["__PHP_Incomplete_Class_Name"]=>
string(4) "test"
["name"]=>
string(2) "hi"
}
Notice: main(): The script tried to execute a method or access a property of an
incomplete object. Please ensure that the class definition "test" of the object you
are trying to operate on was loaded _before_ unserialize() gets called or provide
a __autoload() function to load the class definition in /home/andrew/test2.php
on line 7
NULL
Interestingly, the is_object
method returns false when given an instance of __PHP_Incomplete_Class
. This seems to be in contradiction with var_dump
(as evidenced above), gettype
, and get_class
, all of which return values indicating that the incomplete class is a normal object.
This was reported as bug 19842 way back in 2002, but didn’t seem to be considered a problem. (The suggested solution was simply to have all class definitions present before unserializing that object.)
To be fair, this behavior of is_object
is documented in the notes section of its manual page. It also appears to be intentional, judging from this section in ext/standard/type.c
, determining whether a variable is an object:
220 if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
221 RETURN_FALSE;
222 }
That said, it’s a little confusing when you first run into it, and means that if you’re examining a session for which you don’t have all the class definitions (writing tools outside of your application, for instance), it’s just a little bit harder to determine which variables within the session are objects.
The workaround, of course, is easy, given that most other methods treat the object as an object: $is_object = (get_class($o) !== FALSE);
.