PHP7 и foreach. Коварное изменение?

Как говорится в документации, теперь в PHP7 foreach работает с копией массива, а не с самим массивом.
То есть, раньше этот код работал, а теперь - нет (если не ошибаюсь):
<?php
foreach ($arr as $k=>$v)
{
if ($some_condition==$v) {
   unset($arr[$k]);
}
}

К сожалению, в коде есть некоторые места, которые используют подобную конструкцию.
Получается, нужно с помощью поиска по проекту найти все foreach и заменить $k=>$v на $k=>&$v
Поможет ли это?
Или нужно еще какой-то способ, к примеру (переписать на array_filter)?
Как нужно изменить выше указанный код и нужно ли его изменять вообще?
  • Вопрос задан
  • 4870 просмотров
Решения вопроса 2
OnYourLips
@OnYourLips
Обычно не удаляют неподходящие члены старого массива, а создают новый из подходящих.

$properElements = [];
foreach ($arr as $k => $v)
{
    if ($some_condition != $v) {
        $properElements[] = $v;
    }
}
Ответ написан
@nelson
Читайте официальную документацию по переезду, там всё написано.
php.net/manual/en/migration70.incompatible.php

А именно, по вашему вопросу про foreach:
foreach by-value operates on a copy of the array
When used in the default by-value mode, foreach will now operate on a copy of the array being iterated rather than the array itself. This means that changes to the array made during iteration will not affect the values that are iterated.

Перевод: в режиме foreach($arr as $v) - движок сначала сделает копию массива и будет проводить итерацию по копии. Даже если во время цикла вы сделаете $arr = [], то цикл всё равно пробежит до конца исходного массива, по всем элементам.

То есть код теперь эквивалентен такому:
$arr_copy = $arr;
foreach($arr_copy as $k=>$v) {
...
}
за тем исключением, что к переменной $arr_copy вы не имеете прямого доступа.

Это не значит, что переменная $arr внутри цикла начинает ссылаться на копию. Поэтому Ваш код будет работать.
Вот если бы вы работали в цикле не только с текущим элементом, а например, и со следующими относительно текущего, изменяя или удаляя их, тогда поведение программы изменилось бы. Но я никогда не встречал подобного использования цикла foreach.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
romy4
@romy4
Exception handler
Приведённый код будет нормально работать в php7.
Ответ написан
65536
@65536
в общем то и раньше не стоило менять массив из форыча по нему
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы