Doc #60520 [Opn->Bgs]: Missing behaivour description of unserialization of objects
| From: | bjori@php.net | Date: | Wed, 21 Dec 2011 14:40:11 +0000 |
| Subject: | Doc #60520 [Opn->Bgs]: Missing behaivour description of unserialization of objects | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-7690@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=60520&edit=1
ID: 60520
Updated by: bjori@php.net
Reported by: noxelia at gmail dot com
Summary: Missing behaivour description of unserialization of
objects
-Status: Open
+Status: Bogus
Type: Documentation Problem
Package: Documentation problem
Operating System: LINUX
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
I don't understand why you want that all so explicitly stated.
When you suspend your machine it will execute the sleep routines (not halt), and
when you turn it on again it will execute the resume routines (not bootup).
This is the same with the PHP sleep/wakup. Suspending an object doesn't call its
destruct, and resuming it doesn't call its construct.
If you can think of a specific explanation you'd like to add.. I'd suggest you
modify the file on https://edit.php.net/?
project=PHP&perm=en/language.oop5.magic.php and submit it for review.
Previous Comments:
------------------------------------------------------------------------
[2011-12-14 11:44:30] noxelia at gmail dot com
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 this bug report at https://bugs.php.net/bug.php?id=60520&edit=1