Подводный камень в foreach ($items as &$item)

04.06.2018

Теги: PHPWeb-разработкаЦикл

Многие любят писать такие конструкции в том или ином виде, каждый сталкивался:

foreach ($items as &$item) {
    $item = $item * 2;
}

Если переменной $item предшествует знак амперсанда, это позволяет напрямую изменять элементы массива внутри цикла. В этом случае значение будет присвоено по ссылке. Но не все знают о том, какая опасность тут скрывается.

$items = array(1, 2, 3, 4);
foreach ($items as &$item) {
    $item = $item * 2;
}
// $items = array(2, 4, 6, 8)

// $item все еще ссылается на последний элемент: $items[3]

foreach ($items as $key => $item) {
    // $items[3] будет перезаписываться значениями $item на каждой итерации цикла ...
    echo $key . ' => ' . $item;
    print_r($items);
}
// ... и в конце концов предпоследнее значение определит окончательное содержимое $items[3]
0 => 2  Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 2 )
1 => 4  Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 4 )
2 => 6  Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )
3 => 6  Array ( [0] => 2, [1] => 4, [2] => 6, [3] => 6 )

Надо обязательно уничтожать временную переменную $item с помощью unset():

$items = array(1, 2, 3, 4);
foreach ($items as &$item) {
    $item = $item * 2;
}
unset($item);

Поиск: PHP • Web-разработка • Цикл

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.