Req #27785 [Opn->Wfx]: Change __sleep to always work on copy of object instead of reference
| From: | requinix@php.net | 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