Doc #60520 [NEW]: Missing behaivour description of unserialization of objects
| From: | noxelia at gmail dot com | 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