В Документе об изменениях, несовместимых с предыдущими версиями PHP 7, говорится следующее о foreach:
При использовании в режиме по значению по умолчанию
foreach
теперь будет работать с копией повторяемого массива, а не с самим массивом. Это означает, что изменения в массиве, сделанные во время итерации, не повлияют на итерируемые значения.
Я пытаюсь понять, что это значит, и мой главный вопрос: будет ли этот код работать в PHP 7 так же, как и в PHP 5.6?
foreach($array as $elementKey => $element) {
if ($element == 'x') {
unset($array[$elementKey]);
}
}
Мои два вопроса:
Будет ли этот код работать?
Если да, можете ли вы объяснить (может быть, на примере), что означает это новое изменение в PHP 7?
Изменить
Я перечитал заявление документа. Я думаю, что это означает, что если вы измените значения элементов ниже в массиве, этих изменений не будет, когда вы доберетесь до этих элементов в итерации. Пример:
$array = ['x', 'y', 'z'];
$new = [];
foreach($array as $element) {
if ($element == 'x') {
$array[2] = 'a';
}
$new[] = $element;
}
print_r($new);
Однако, когда я запускаю этот пример, кажется, нет никакой разницы в версиях PHP (хотя я никогда раньше не пользовался этим инструментом, поэтому не знаю, как он работает).
Я понимаю, что если я сделаю это по ссылке, я получу a
в новом. Иначе не буду. Но это похоже на обе версии.
Что мне действительно нужно знать, так это что такое несовместимость (на примере)?
Изменить 2
ссылка на ответ, предложенная @NikiC, содержит остальную часть истории, которую я искал:
В большинстве случаев это изменение прозрачно и не имеет никакого другого эффекта, кроме повышения производительности. Однако есть один случай, когда это приводит к другому поведению, а именно к случаю, когда массив был заранее ссылкой:
$array = [1, 2, 3, 4, 5];
$ref = &$array;
foreach ($array as $val) {
var_dump($val);
$array[2] = 0;
}
/* Old output: 1, 2, 0, 4, 5 */
/* New output: 1, 2, 3, 4, 5 */
Раньше итерация массивов ссылок по значению была частным случаем. В этом случае дублирования не произошло, поэтому все изменения массива во время итерации будут отражены в цикле. В PHP 7 этот особый случай исчез: итерация массива по значению всегда будет продолжать работать с исходными элементами, не обращая внимания на любые модификации во время цикла.
Этот ответ объясняет редкий «особый случай», когда в разных версиях все работает по-разному в отношении foreach
работы с копией массива.