Если я перебираю массив дважды, один раз по ссылке и затем по значению, PHP будет перезаписывать последнее значение в массиве, если я использую одно и то же имя переменной для каждого цикла. Это лучше всего иллюстрируется на примере:
$array = range(1,5); foreach($array as &$element) { $element *= 2; } print_r($array); foreach($array as $element) { } print_r($array);
Вывод:
Массив ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
Массив ([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8 )
Обратите внимание, что я не ищу исправления, я хочу понять, почему это происходит. Также обратите внимание, что это не происходит, если имена переменных в каждом цикле не называются как $element
, поэтому я предполагаю, что это связано с $element
все еще находящимся в области видимости, и ссылкой после окончания первого цикла.
После того, как первый элемент цикла $ по-прежнему является ссылкой на последний элемент / значение массива $.
Вы можете видеть, что при использовании var_dump () вместо print_r ()
array(5) { [0]=> int(2) ... [4]=> &int(2) }
Обратите внимание, что & in &int(2)
.
Во втором цикле вы присваиваете значения элементу $. И поскольку это еще ссылка, значение в массиве также изменяется. Попробуйте
foreach($array as $element) { var_dump($array); }
как второй цикл, и вы увидите.
Так что это более или менее то же самое, что и
$array = range(1,5); $element = &$array[4]; $element = $array[3]; // and $element = $array[4]; echo $array[4];
(только с циклами и умножением … эй, я сказал «более или менее» ;-))
Вот объяснение от самого человека :
$y = "some test"; foreach ($myarray as $y) { print "$y\n"; }
Здесь
$y
– это запись таблицы символов, ссылающаяся на строку, содержащую «некоторый тест». На первой итерации вы по существу делаете:$y = $myarray[0]; // Not necessarily 0, just the 1st element
Итак, теперь хранилище, связанное с
$y
, перезаписывается значением из$myarray
. Если$y
связано с некоторым другим хранилищем через ссылку, это хранилище будет изменено.Теперь предположим, что вы это делаете:
$myarray = array("Test"); $a = "A string"; $y = &$a; foreach ($myarray as $y) { print "$y\n"; }
Здесь
$y
ассоциируется с тем же хранилищем, что и$a
через ссылку, поэтому, когда выполняется первая итерация:$y = $myarray[0];
Единственное место, куда может идти строка «Тест», – это хранилище, связанное с
$y
.
Вот как вы могли бы решить эту проблему:
foreach($array as &$element) { $element *= 2; } unset($element); #gets rid of the reference and cleans the var for re-use. foreach($array as $element) { }
сforeach($array as &$element) { $element *= 2; } unset($element); #gets rid of the reference and cleans the var for re-use. foreach($array as $element) { }