Выбор ответа Senior Массивы изнутри обновлено

Изменение массива внутри foreach

Вопрос

Что выведут два цикла?

$a = [1, 2, 3];
foreach ($a as $v) {
    if ($v === 1) { $a[] = 4; }
    echo "$v ";
}
echo count($a), "\n";

$b = [1, 2, 3];
foreach ($b as &$v) {
    if ($v === 1) { $b[] = 4; }
    echo "$v ";
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: 1 2 3 4 и 1 2 3 4. В PHP 7+ foreach по значению перебирает исходное состояние массива: добавление элемента внутри цикла отделяет копию (copy-on-write), и цикл её не видит.

Варианты ответа

  1. 1 2 3 3 и 1 2 3 4
  2. 1 2 3 4 и 1 2 3 4правильный ответ
  3. 1 2 3 4 и 1 2 3
  4. Бесконечный цикл во втором случае

Разбор

В PHP 7+ foreach по значению перебирает исходное состояние массива: добавление элемента внутри цикла отделяет копию (copy-on-write), и цикл её не видит. Печатаются 1 2 3, затем count уже 4. foreach по ссылке работает с самим массивом и видит добавленный элемент, поэтому печатает 1 2 3 4. В PHP 5 поведение зависело от внутреннего указателя массива и было менее предсказуемым.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.