Не уверен, если это считается ошибкой
$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];
}
Печать
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)
}
}
Обратите внимание, что $ array не был передан по ссылке на modify_array (), однако вложенный массив был изменен. Звучит логично, но не уверен, что это задокументировано!
Если вы используете foreah со ссылкой, вы запрещаете PHP делать копию массива, поэтому вы работаете с оригинальным массивом. Когда вы закончите цикл foreach, вы должны unset()
переменная используется в цикле, потому что она все еще остается в памяти. Если вы этого не сделаете, вы получите непредсказуемые результаты, подобные представленным в вашем вопросе. Даже в документация у вас есть предупреждение:
Предупреждение Ссылка $ значение и последний элемент массива остается даже после для каждого петля. Рекомендуется уничтожить его
снята с охраны ().
Вот Вы можете найти действительно хорошие примеры циклов foreach без сброса.
Так что, если вы добавите unset()
все выглядит как надо
$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];
}
Результат:
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) } }
Если вы перепишите следующий код:
foreach ($array as &$numbers) {
$numbers = [4, 5, 6];
}
Что-то вроде этого:
$array['numbers'] = &$array['numbers'];
$array['numbers'] = [4,5,6];
Такое поведение будет легче понять, и это, кажется, известная проблема.
(Увидеть: http://php.net/manual/en/language.references.php#87532)