note 123644 added to language.oop5.references
| From: | JoeF@php.net | Date: | Fri, 01 Mar 2019 01:38:14 +0000 |
| Subject: | note 123644 added to language.oop5.references | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-210291@lists.php.net to get a copy of this message | ||
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!'); // Constructed: foo => Hello!
$new_foo = new foo('new_foo', 'New Foo 2!'); // Constructed: new_foo => New
Foo 2!
$third_foo = new foo('third_foo', 'Final Foo!'); // Constructed: third_foo =>
Final Foo!
$foo->store_object($new_foo);
$foo->store_object2($third_foo);
$foo->stored_method('store_object', array($third_foo)); //Call stored method:
store_object{ }
$serialized = serialize($foo);
unset($foo);
unset($new_foo);
unset($third_foo);
$unserialized_foo = unserialize($serialized);
//Below, I update the object represented as A(c) but I update it via the A object
$unserialized_foo->stored_method2('store_value', array('Super Last Foo!'));
// Call stored method 2: store_value{}
$unserialized_foo->echo_value(); // Value: Hello!
$unserialized_foo->stored_method('echo_value', array());
//Call stored method: echo_value{
//Value: New Foo 2!
//}
// Last, I check the value of A(c) as it was stored in A(b) to see if updating A(c) via A also
updates A(b)'s copy/reference:
$unserialized_foo->stored_method('stored_method', array('echo_value',
array()));
//Call stored method: stored_method{
//Call stored method: echo_value{
//Value: Super Last Foo!
//}
//}
?>
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.
----
Server IP: 208.43.231.9
Probable Submitter: 185.85.3.194 (proxied: 38.27.141.141)
----
Manual Page -- http://php.net/manual/en/language.oop5.references.php
Edit -- https://master.php.net/note/edit/123644
Del: integrated -- https://master.php.net/note/delete/123644/integrated
Del: useless -- https://master.php.net/note/delete/123644/useless
Del: bad code -- https://master.php.net/note/delete/123644/bad+code
Del: spam -- https://master.php.net/note/delete/123644/spam
Del: non-english -- https://master.php.net/note/delete/123644/non-english
Del: in docs -- https://master.php.net/note/delete/123644/in+docs
Del: other reasons-- https://master.php.net/note/delete/123644
Reject -- https://master.php.net/note/reject/123644
Search -- https://master.php.net/manage/user-notes.php