I am planning to serialize and unserialize objects as a means of storage, and my application can conveniently group large numbers of objects inside of a single object to serialize. However, this presented some questions that I needed to answer:
Let's say the parent object I plan to serialize is "A" and the objects I store in it will be A(a-z). If I pass A(b) to A(c), this happens by reference. So if A(c) takes actions that effect the values of A(b), this will also update the original A(b) stored in A. Great!
However, what happens when I serialize A, where A(c) has a reference to A(b), and then I unserialize? Will A(c) have a new unique copy of A(b), or will it still reference the A(b) stored in A?
The answer is, PHP 5.5 and PHP 7 both track whether something is a reference to an object it's already "recreated" during the unserialize process, see this example:
<?php
class foo {
protected $stored_object;
protected $stored_object2;
protected $stored_value;
public function __construct($name, $stored_value) {
$this->store_value($stored_value);
echo 'Constructed: '.$name.' => '.$stored_value.'<br/>';
}
public function store_object(foo $object) {
$this->stored_object = $object;
}
public function store_object2(foo $object) {
$this->stored_object2 = $object;
}
public function store_value($value) {
$this->stored_value = $value;
}
public function stored_method($method, array $parameters) {
echo 'Call stored method: '.$method.'{ <br/>';
call_user_func_array(array($this->stored_object, $method), $parameters);
echo '} <br/>';
}
public function stored_method2($method, array $parameters) {
echo 'Call stored method 2: '.$method.'{ <br/>';
call_user_func_array(array($this->stored_object2, $method), $parameters);
echo '} <br/>';
}
public function echo_value() {
echo 'Value: '.$this->stored_value.'<br/>';
}
}
$foo = new foo('foo', 'Hello!'); $new_foo = new foo('new_foo', 'New Foo 2!'); $third_foo = new foo('third_foo', 'Final Foo!'); $foo->store_object($new_foo);
$foo->store_object2($third_foo);
$foo->stored_method('store_object', array($third_foo)); $serialized = serialize($foo);
unset($foo);
unset($new_foo);
unset($third_foo);
$unserialized_foo = unserialize($serialized);
$unserialized_foo->stored_method2('store_value', array('Super Last Foo!')); $unserialized_foo->echo_value(); $unserialized_foo->stored_method('echo_value', array());
$unserialized_foo->stored_method('stored_method', array('echo_value', array()));
?>
Per the last line, A(b)'s "copy" of A(c) is still a reference to the original A(b) as stored in A, even after unserializing.