После первого цикла foreach, $item
все еще остается ссылка на некоторое значение, которое также используется $arr[2]
. Таким образом, каждый вызов foreach во втором цикле, который не вызывается по ссылке, заменяет это значение и, таким образом $arr[2]
, новым значением.
Таким образом, цикл 1, значение и $arr[2]
стать $arr[0]
, что является 'Foo'.
Цикл 2, значение и $arr[2]
стать $arr[1]
, который является «бар».
Цикл 3, значение и $arr[2]
стать $arr[2]
, который является «бар» (из-за цикла 2).
Значение baz фактически теряется при первом вызове второго цикла foreach.
Отладка вывода
Для каждой итерации цикла мы будем $item
выводить значение, а также рекурсивно выводить массив$arr
.
Когда первый цикл проходит, мы видим этот вывод:
foo
Array ( [0] => foo [1] => bar [2] => baz )
bar
Array ( [0] => foo [1] => bar [2] => baz )
baz
Array ( [0] => foo [1] => bar [2] => baz )
В конце цикла $item
все еще указывает на то же место, что и $arr[2]
.
Когда второй цикл проходит, мы видим этот вывод:
foo
Array ( [0] => foo [1] => bar [2] => foo )
bar
Array ( [0] => foo [1] => bar [2] => bar )
bar
Array ( [0] => foo [1] => bar [2] => bar )
Вы заметите, как каждый раз, когда массив помещает новое значение $item
, он также обновляется $arr[3]
тем же значением, так как они все еще указывают на одно и то же местоположение. Когда цикл достигает третьего значения массива, он будет содержать значение, bar
потому что оно было просто установлено предыдущей итерацией этого цикла.
Это ошибка?
Нет. Это поведение ссылочного элемента, а не ошибка. Это было бы похоже на запуск чего-то вроде:
for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }
Цикл foreach не является особенным по своей природе, в котором он может игнорировать ссылочные элементы. Это просто установка этой переменной на новое значение каждый раз, как если бы вы были вне цикла.