{"id":200,"date":"2009-05-17T14:58:04","date_gmt":"2009-05-17T18:58:04","guid":{"rendered":"http:\/\/blogs.n1zyy.com\/andrew\/?p=200"},"modified":"2009-05-17T14:58:04","modified_gmt":"2009-05-17T18:58:04","slug":"when-objects-arent","status":"publish","type":"post","link":"https:\/\/blogs.n1zyy.com\/andrew\/2009\/05\/17\/when-objects-arent\/","title":{"rendered":"When Objects Aren&#8217;t"},"content":{"rendered":"<p>When unserializing an object whose class definition is not present, PHP returns an instance of the special type, <code>__PHP_Incomplete_Class<\/code>, which issues notices if you attempt to call a method or access a property.<\/p>\n<p>For example, <a href=\"http:\/\/dothedrew.net\/misc\/incomplete.phps\">this code<\/a> produces the following:<\/p>\n<pre><code>andrew@fake:~$ php incomplete.php\nobject(__PHP_Incomplete_Class)#1 (2) {\n  [\"__PHP_Incomplete_Class_Name\"]=&gt;\n  string(4) \"test\"\n  [\"name\"]=&gt;\n  string(2) \"hi\"\n}\n\nNotice: main(): The script tried to execute a method or access a property of an\nincomplete object. Please ensure that the class definition \"test\" of the object you\nare trying to operate on was loaded _before_ unserialize() gets called or provide\na __autoload() function to load the class definition  in \/home\/andrew\/test2.php\non line 7\nNULL<\/code><\/pre>\n<p>Interestingly, the <code>is_object<\/code> method returns false when given an instance of <code>__PHP_Incomplete_Class<\/code>. This seems to be in contradiction with <code>var_dump<\/code> (as evidenced above), <code>gettype<\/code>, and <code>get_class<\/code>, all of which return values indicating that the incomplete class is a normal object.<\/p>\n<p>This was reported as <a href=\"http:\/\/bugs.php.net\/bug.php?id=19842\">bug 19842<\/a> way back in 2002, but didn&#8217;t seem to be considered a problem. (The suggested solution was simply to have all class definitions present before unserializing that object.)<\/p>\n<p>To be fair, this behavior of <code>is_object<\/code> is documented in the notes section of its <a href=\"http:\/\/us2.php.net\/is_object\">manual page<\/a>. It also appears to be intentional, judging from this section in <code>ext\/standard\/type.c<\/code>, determining whether a variable is an object:<\/p>\n<pre><code>   220                          if (!strcmp(ce-&gt;name, INCOMPLETE_CLASS)) {\n   221                                  RETURN_FALSE;\n   222                          }<\/code><\/pre>\n<p>That said, it&#8217;s a little confusing when you first run into it, and means that if you&#8217;re examining a session for which you don&#8217;t have all the class definitions (writing tools outside of your application, for instance), it&#8217;s just a little bit harder to determine which variables within the session are objects.<\/p>\n<p>The workaround, of course, is easy, given that most other methods treat the object as an object: <code>$is_object = (get_class($o) !== FALSE);<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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) { [&#8220;__PHP_Incomplete_Class_Name&#8221;]=&gt; string(4) &#8220;test&#8221; [&#8220;name&#8221;]=&gt; string(2) &#8220;hi&#8221; } Notice: main(): [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-200","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/posts\/200","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/comments?post=200"}],"version-history":[{"count":0,"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/posts\/200\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/media?parent=200"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/categories?post=200"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.n1zyy.com\/andrew\/wp-json\/wp\/v2\/tags?post=200"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}