Why the following code has the different output in PHP 5.5.* and PHP 7.*:
<?php
$foo = ['bar'=>[['item1'=>'value1']]];
foreach ($foo['bar'] ?: [] as $k => &$arr1) {
$arr1['item1'] = 'value2';
}
var_dump($foo);
In PHP 5 value of $foo['bar'][0]['item1']
will be modified with the value2
, but in PHP 7 it will not.
From the documentation (emphasis mine): Please note that the ternary operator is an expression, and that it doesn't evaluate to a variable, but to the result of an expression. This is important to know if you want to return a variable by reference. The statement return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued.
With PHP 5, note how the innermost &array(1)
is a reference:
array(1) {
["bar"]=>
array(1) {
[0]=>
&array(1) {
["item1"]=>
string(6) "value2"
}
}
}
But with PHP 7, it is not:
array(1) {
["bar"]=>
array(1) {
[0]=>
array(1) {
["item1"]=>
string(6) "value1"
}
}
}
If you remove ?: []
, so the expression you're looping through is simply $foo['bar']
, then the code behaves the same with both PHP 5 and 7, i.e. the innermost &array(1)
is a reference.
TLDR: I can't say why this is, or where the difference is explained, but it seems clear that PHP 7 handles the conditional operator ?:
differently than does PHP 5.