Doc #60520 [NEW]: Missing behaivour description of unserialization of objects

From: Date: Wed, 14 Dec 2011 11:44:31 +0000
Subject: Doc #60520 [NEW]: Missing behaivour description of unserialization of objects
Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-7655@lists.php.net to get a copy of this message
From: Operating system: LINUX PHP version: Irrelevant Package: Documentation problem Bug Type: Documentation Problem Bug description:Missing behaivour description of unserialization of objects Description: ------------ --- From manual page: r2.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep --- These apply to objects that do NOT implement Serializable, rather they implement __sleep() and __wakeup. It should be clearly stated that a) unseriaze() does not call __construct() b) It is a bad practice to call __construct() from __wakeup() Test script: --------------- <?php /* BASED ON the below example from dhuseby domain getback tld com 01-Mar-2008 02:22 this examples pinpoints the constructor behaiviour from unserialized objects using __sleep and __wakeup and proposes a method to overcome initialization issues. */ ?> <?php class Base { private $foo = "Base::foo_null"; protected $bar = "Base::bar_null"; public function __construct() { $this->foo = "Base::foo_constructed"; $this->bar = "Base::bar_constructed"; echo "THE BASE CONSTRUCTOR\n"; } public function set() { $this->bar = "Base::bar_set"; } public function __sleep() { return array("\0Base\0foo", "\0*\0bar"); } } class Derived extends Base { public $baz = "Derived::baz_null"; private $boo = "Derived::boo_null"; public function __construct() { parent::__construct(); self::init(); $this->boo = "Derived::boo_constructed"; echo "THE DERIVED CONSTRUCTOR\n"; } public function set() { $this->boo = "Derived::boo_set"; } public function init() { // initialize non serialized vars $this->baz = "Derived::baz_constructed"; } public function __sleep() { // we have to merge our members with our parent's // omit baz return array_merge(array("\0Derived\0boo"), parent::__sleep()); } public function __wakeup() { // re initialize // THIS DESTROYS UNSERIALIZED VALUES self::__construct(); // this initializes non serializable vars $this->init(); } } class Leaf extends Derived { private $qux = "Leaf::qux_null"; protected $zaz = "Leaf::zaz_null"; public $blah = "Leaf::blah_null"; public function __construct() { parent::__construct(); $this->qux = "Leaf::qux_constructed"; $this->zaz = "Leaf::zaz_constructed"; $this->blah = "Leaf::blah_constructed"; echo "THE LEAF CONSTRUCTOR\n"; } public function __sleep() { // again, merge our members with our parent's // omot zaz return array_merge(array("\0Leaf\0qux", "blah"), parent::__sleep()); } public function set() { $this->blah = "Leaf::blah_set"; parent::set(); } } echo "SERIALIZATION TEST\n"; // test it echo "CO\n"; $test = new Leaf(); $test->set(); $s = serialize($test); echo "UN\n"; $test2 = unserialize($s); echo "\nORIGINAL\n"; print_r($test); echo "\nSSER ".$s."\n"; echo "\nUNSERIALIZED\n"; print_r($test2); ?> <? /* RESULTS ------- 1) *****IMPORTANT AND NOT DOCUMENTED**** __constructor() is not called from unserialize (variable Leaf::zaz has the definition value after initialization and not the constuctor assigned value) 2) __wakeup() is executed after actual data unserialization, so it is pointless to call __construct() from __wakeup() since it overwrites unserialized data width constructor assigned data 3) A possible design pattersn that can solve the initialization of unserialized variables, is is to segment initialization variables into those that need initialization (and not serialized) and those that will be serialized. Then create an init() function that initializes unserializable variables and call the init() from __wakeup() (and from __contruct() ) */ -- Edit bug report at https://bugs.php.net/bug.php?id=60520&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=60520&r=trysnapshot54 Try a snapshot (PHP 5.3): https://bugs.php.net/fix.php?id=60520&r=trysnapshot53 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=60520&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=60520&r=fixed Fixed in SVN and need be documented: https://bugs.php.net/fix.php?id=60520&r=needdocs Fixed in release: https://bugs.php.net/fix.php?id=60520&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=60520&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=60520&r=needscript Try newer version: https://bugs.php.net/fix.php?id=60520&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=60520&r=support Expected behavior: https://bugs.php.net/fix.php?id=60520&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=60520&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=60520&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=60520&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=60520&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=60520&r=dst IIS Stability: https://bugs.php.net/fix.php?id=60520&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=60520&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=60520&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=60520&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=60520&r=mysqlcfg

« previous php.doc.bugs (#7655) next »