I'm puzzled by the behaviour in the following example. I stumbled over this in a project and it took me hours to narrow the problem down to a simple example. So this is my simple test class:
<?php
class Foo {
public $sess = [['name' => 'John']];
public function info() {
$this->runTest();
echo $this->sess[0]['name'];
}
private function runTest() {
$localSess = &$this->sess[0];
$this->sessTest();
}
private function sessTest() {
$sessCopy = $this->sess;
$this->sess[0]['name'] = 'Bob';
$this->sess = $sessCopy;
}
}
$myFoo = new Foo;
$myFoo->info();
The unexpected resulting output is:
Bob
If $localSess
is just a simple assignment and not a reference, the output is (as expected): John
I don't understand what's going on here. Since the class property $sess
is an array and not an object, the assignment to $sessCopy
should be a simple copy. But if you print the content of $sessCopy
right after modifying $this->sess
, it will contain the changed value for 'name'. So it seems as if $sessCopy
were a reference after all? But only if $localSess
in the calling method is a reference. Why should that even matter? BTW, if $localSess
is a reference to the whole array of the class property and not just to its first index, everything works as expected.
Can someone please shed some light on this? If the mere existence of a variable reference in one function can influence the content of a local variable (not a reference!) in another function, then that seems dangerous and scary.
My Answer:
php
class Test {
private $data = [];
public function addValue(&$value) {
$this->data[] = $value;
}
public function printData() {
print_r($this->data);
}
}
$obj = new Test();
$value = 1;
$obj->addValue($value);
$obj->printData(); // Output: Array ( [0] => 1 )
$value = 2;
$obj->printData(); // Output: Array ( [0] => 2 )
In this example, we have a `Test` class with a private property `$data` which is an array. We have two methods: `addValue` which takes a reference to a variable and adds it to the `$data` array, and `printData` which simply prints out the contents of the `$data` array.
When we create an instance of the `Test` class and call `addValue` with a variable `$value`, it adds the value of `$value` to the `$data` array. However, when we change the value of `$value` and call `printData` again, the value in the `$data` array also changes. This is because we passed `$value` by reference to the `addValue` method, so any changes to `$value` outside of the method will affect the value in the `$data` array.
To avoid this behavior, you can remove the reference in the `addValue` method signature like this:
php
public function addValue($value) {
$this->data[] = $value;
}
Now, changing the value of `$value` outside of the method will not affect the value in the `$data` array.
Rate this post
5 of 5 based on 2944 votesComments