Req #27785 [Opn->Wfx]: Change __sleep to always work on copy of object instead of reference

From: Date: Sat, 01 Nov 2014 22:19:30 +0000
Subject: Req #27785 [Opn->Wfx]: Change __sleep to always work on copy of object instead of reference
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-188403@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=27785&edit=1 ID: 27785 Updated by: requinix@php.net Reported by: brad at info-link dot net Summary: Change __sleep to always work on copy of object instead of reference -Status: Open +Status: Wont fix Type: Feature/Change Request -Package: Feature/Change Request +Package: *General Issues Operating System: Linux PHP Version: 5.0.0RC1 Block user comment: N Private report: N New Comment: __sleep/wakeup provide only very simple functionality. PHP 5.1.0 introduced the Serializable interface which gives much more control, allowing you to provide exactly the data you want to serialize without having to modify the object. http://php.net/manual/en/class.serializable.php public function serialize() { $vars = get_object_vars($this); unset($vars["a"]); // don't serialize this property return serialize($vars); } public function unserialize($string) { $vars = unserialize($string); // no $vars["a"] means $this->a will keep its current (ie, default) value foreach ($vars as $key => $value) $this->$key = $value; } Previous Comments: ------------------------------------------------------------------------ [2004-03-30 17:20:43] brad at info-link dot net Description: ------------ When serializing an object with a __sleep method defined, the original object may be modified by __sleep. I'd like to see the __sleep method always being called on a copy of the object being serialized and not on the actual object. In PHP4, this is _mostly_ the case as long as you're not working with references, but in PHP5, the original object is always modified directly. The example below is a little contrived, but does demonstrate the idea. Under PHP4, the result is _almost_ as expected, except that the instance of B referenced by $a->b is modified. If the reference is changed to a plain copy (change the line reading "$a->b = &$b;" to "$a->b = $b;"), then the instance is not modified. PHP5 gives the output given under actual result, which is probably wrong in either case. Reproduce code: --------------- <?php class B { var $b = 'default'; function __sleep() { $this->b = 'serialized'; return Array('b'); } } class A { var $a = "default"; var $b = null; function __sleep() { $this->a = "serialized"; return array_keys(get_object_vars($this)); } } $a = new A(); $b = new B(); $a->b = &$b; print_r($a); $s = serialize($a); print_r($s); print_r($a); $na = unserialize($s); print_r($na); ?> Expected result: ---------------- a Object ( [a] => default [b] => b Object ( [b] => default ) ) O:1:"a":2:{s:1:"a";s:10:"serialized";s:1:"b";O:1:"b":1:{s:1:"b";s:10:"serialized";}}a Object ( [a] => default [b] => b Object ( [b] => default ) ) a Object ( [a] => serialized [b] => b Object ( [b] => serialized ) ) Actual result: -------------- A Object ( [a] => default [b] => B Object ( [b] => default ) ) O:1:"A":2:{s:1:"a";s:10:"serialized";s:1:"b";O:1:"B":1:{s:1:"b";s:10:"serialized";}}A Object ( [a] => serialized [b] => B Object ( [b] => serialized ) ) A Object ( [a] => serialized [b] => B Object ( [b] => serialized ) ) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=27785&edit=1

« previous php.bugs (#188403) next »