Just a quick brain dump regarding serializing classes in PHP. There is nothing advanced about this, and TBH I haven’t even read up on the caveats of serializing classes in PHP – perhaps a task for another day.
Judging from the string output after serializing the class, it appears that it is simply a named object. When unserializing, the class must be defined to unserialize completely, otherwise you’re stuck with an instance of __PHP_Incomplete_class. Hint: when in the same file, class definitions work just like function definitions, i.e. you can put them anywhere, before or after target code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<?php // class definition class T { public $one = '1'; public $two = 2; public $three = false; protected $four = array(1,2,3); private $five; public function __construct($five) { $this->five = $five; } public function getStuff() { return array($this->one,$this->two,$this->three,$this->four,$this->five); } } $t = new T(42); // instantiate $s = serialize($t); // turn the class into a string representation var_dump($s); // this shows the new serialized class instance as a string $u = unserialize($s); // ok open it back up as a class object/instance var_dump($u); // and what does it look like? var_dump($u->getStuff()); // we can even call methods on the newly "created" class var_dump($u instanceof T); // yes, it is an instance // ok so now something a bit more tricky, I changed the class name to "X" instead of "T" $sx = str_replace('T','X',$s); // remember, class X hasn't been declared $ux = unserialize($sx); // works var_dump($ux); // has a bunch of __PHP_Incomplete_Class* var_dump($ux instanceof T); // nope, not the same anymore var_dump($ux instanceof __PHP_Incomplete_Class); // true! oh man... the mysterious internals of PHP var_dump($ux->getStuff()); // Fatal Error, oh noz. var_dump($ux->two); // this also gives a fatal error /* Fatal error: Unknown: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "X" 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. */ ?> |
Notice the Fatal Error above. This example didn’t follow my instructions of having the class “X” defined. To remedy this, simply:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php // if we include class X extends T {} // then we can $ux->getStuff(); // or we can $ux->two; // and also var_dump($ux instanceof X); // true var_dump($ux instanceof T); // true var_dump($ux instanceof __PHP_Incomplete_Class); // false ?> |
And now, with both PHP snippets merged into a single file, this is what the output looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
string 'O:1:"T":5:{s:3:"one";s:1:"1";s:3:"two";i:2;s:5:"three";b:0;s:7:"�*�four";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}s:7:"�T�five";i:42;}' (length=123) object(T)[2] public 'one' => string '1' (length=1) public 'two' => int 2 public 'three' => boolean false protected 'four' => array (size=3) 0 => int 1 1 => int 2 2 => int 3 private 'five' => int 42 array (size=5) 0 => string '1' (length=1) 1 => int 2 2 => boolean false 3 => array (size=3) 0 => int 1 1 => int 2 2 => int 3 4 => int 42 boolean true object(X)[3] public 'one' => string '1' (length=1) public 'two' => int 2 public 'three' => boolean false protected 'four' => array (size=3) 0 => int 1 1 => int 2 2 => int 3 private 'five' (T) => null private 'five' => int 42 boolean true boolean false array (size=5) 0 => string '1' (length=1) 1 => int 2 2 => boolean false 3 => array (size=3) 0 => int 1 1 => int 2 2 => int 3 4 => null int 2 boolean true boolean true boolean false |