Після першого циклу 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 не має особливого характеру, в якому він може ігнорувати посилання на елементи. Це просто встановити цю змінну на нове значення кожного разу, як ви б знаходились поза циклом.