PHP 5.5.12. Consider this:
<?php
$a = [ 'a', 'b', 'c' ];
foreach($a as &$x) {
$x .= 'q';
}
print_r($a);
This, as expected, outputs:
Array
(
[0] => aq
[1] => bq
[2] => cq
)
Now consider:
<?php
$a = [ 'a', 'b', 'c' ];
foreach(z($a) as &$x) {
$x .= 'q';
}
print_r($a);
function z($a)
{
return $a;
}
This outputs:
Array
(
[0] => aq
[1] => bq
[2] => cq
)
(!) But wait a minute. $a is not being passed by reference. Which means I should be getting a copy back from z(), which would be modified, and $a ought to be left alone.
But what happens when we force PHP to do its copy-on-write magic:
$a = [ 'a', 'b', 'c' ];
foreach(z($a) as &$x) {
$x .= 'q';
}
print_r($a);
function z($a)
{
$a[0] .= 'x';
return $a;
}
For this, we get what I would expect:
Array
(
[0] => a
[1] => b
[2] => c
)
EDIT: One more example...
$a = [ 'a', 'b', 'c' ];
$b = z($a);
foreach($b as &$x) {
$x .= 'q';
}
print_r($a);
function z($a)
{
return $a;
}
This works as expected:
Array
(
[0] => a
[1] => b
[2] => c
)
Is there a rational explanation for this?