Adding references in PHP to an array creates an array of references
Not sure if this is considered a bug
$array = ['numbers' => [1, 2, 3]];
foreach ($array as &$numbers) {
$numbers = [4, 5, 6];
}
var_dump($array);
modify_array($array);
var_dump($array);
function modify_array($array_arg)
{
$array_arg['numbers'] = [1, 2, 3];
}
Prints
array(1) {
["numbers"]=>
&array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
}
array(1) {
["numbers"]=>
&array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
}
Notice that $array was not passed by reference to modify_array() however the nested array was modified. It sounds logical but not sure if this is documented!
If you are using foreah with reference you prevent PHP to make a copy of array, so you are working on original array. When you finish foreach loop you should unset()
variable used in loop, because it still remains in memory. If you don't do this, you will get unpredictable results like this one presented in your question. Even in documentation you have a warning:
Warning Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
Here you can find really good examples of foreach loops without unsetting.
So if you add unset()
, everything looks as it should
$array = ['numbers' => [1, 2, 3]];
foreach ($array as &$numbers) {
$numbers = [4, 5, 6];
}
unset($numbers);
var_dump($array);
modify_array($array);
var_dump($array);
function modify_array($array_arg) {
$array_arg['numbers'] = [1, 2, 3];
}
Result:
array(1) { ["numbers"]=> array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) } }
array(1) { ["numbers"]=> array(3) { [0]=> int(4) [1]=> int(5) [2]=> int(6) } }
If you rewrite following code:
foreach ($array as &$numbers) {
$numbers = [4, 5, 6];
}
To smth like this:
$array['numbers'] = &$array['numbers'];
$array['numbers'] = [4,5,6];
It'll be easier to understand such a behavior, and this seems to be a known issue. (See: http://php.net/manual/en/language.references.php#87532)
链接地址: http://www.djcxy.com/p/81474.html