note 48451 deleted from function.serialize by aharvey
| From: | aharvey@php.net | Date: | Tue, 06 Nov 2012 02:07:33 +0000 |
| Subject: | note 48451 deleted from function.serialize by aharvey | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-191756@lists.php.net to get a copy of this message | ||
Note Submitter: cjmeyer at npcc dot net
----
More on troubles with recursive object references and serialization.
In my PHP 4.2.2 the solution suggested above (by james at gogo dot co dot nz), to pass a reference
to the object to serialize(), does not help. There are still multiple copies of the objects woken
up, and the recursive reference is no longer recursive.
The only solution I have found is to use the __sleep and __wakeup magic functions to only serialize
the link one-way, then recreate it manually on unserialize. This isn't too difficult; here is
some code demonstrating this approach:
class A {
var $data = Null;
var $b = Null;
function A($data, $bData) {
$this->data = $data;
$this->b = new B(&$this, $bData);
}
function printData() {
print 'A thinks A data is ' . $this->data . "\n";
print 'A thinks B data is ' . $this->b->data . "\n";
}
function __sleep() {
print "A is going to sleep.\n";
return array('data', 'b');
}
function __wakeup(){
print "A is waking up.\n";
$this->b->reLinkA($this);
}
}
class B {
var $data = Null;
var $a = Null;
function B(&$a, $data) {
$this->a =& $a;
$this->data = $data;
}
function printData() {
print 'B thinks A data is ' . $this->a->data . "\n";
print 'B thinks B data is ' . $this->data . "\n";
}
function __sleep() {
print "B is going to sleep.\n";
return array('data');
}
function __wakeup(){
print "B is waking up.\n";
}
function reLinkA(&$a) {
$this->a =& $a;
}
}
$a = new A("origAdata", "origBdata");
print '<pre>';
print "I think A data is " . $a->data . "\n";
print "I think B data is " . $a->b->data . "\n";
$a->printData();
$a->b->printData();
$serA = serialize($a);
$newA = unserialize($serA);
$newA->data = 'newAdata';
$newA->b->data = 'newBdata';
print "I think new A data is " . $newA->data . "\n";
print "I think new B data is " . $newA->b->data . "\n";
$newA->printData();
$newA->b->printData();