Изменения, внесенные в PHP 7 в оператор foreach

В этой статье мы рассмотрим изменения использования оператора PHP foreach, внесенные в 7 версию языка.

Несовместимые изменения оператора foreach в PHP 7

Все изменения в операторе foreach относятся к переборке указателей массива и его модификации. Ниже приведены изменения, несовместимые с более старыми версиями.

  • Оператор foreach не изменяет внутренний указатель массива: В PHP версии 5.x и более ранних можно было изменять внутренний указатель массива во время его обработки массива с помощью foreach. Но в PHP 7 эта функция была полностью удалена.

    Чтобы лучше понять это, рассмотрим следующий пример:

<html>
   <head>
      <title><?php echo "Welcome to PHP-7 Tutorials";?></title>      
   </head>
   <body>
<?php
$array = [10, 20, 30, 40];
foreach ($array as &$val) {
    var_dump(current($array));
}
?>  
   </body>
</html>

Пояснение кода PHP 7

  • Мы объявляем массив из четырех элементов [10, 20, 30, 40];
  • Затем мы используем цикл foreach PHP для перебора массива и внутри цикла выводим информацию о переменной с помощью функции var_dump.
  • Внутри этой функции мы используем текущую функцию, которая содержит массив в качестве входных данных. Текущая функция используется для возврата текущего элемента в массиве.

Результат

Когда мы выполняем этот код PHP 7 на сервере, то не сможем изменить внутренний указатель массива:

Результат
  • foreach (по значению) работает с копией массива: В PHP 7, если мы используем foreach в режиме по умолчанию by-value, он будет работать с копией массива, а не с оригиналом. Это гарантирует, что изменения, которые были внесены во время обработки, не повлияют на значения фактического массива;
  • foreach (по ссылке) получил улучшенное поведение при итерациях: В PHP 7 была введена улучшенная версия foreach с точки зрения поведения перебора. После этого улучшения цикл во время перебора массива по ссылке способен отслеживать изменения, внесенные в массив. В PHP 5.x и более ранних версиях PHP array foreach игнорировал вновь добавляемые во время перебора массива элементы и не отображал их.

    Чтобы лучше понять это, рассмотрим следующий пример:

<html>
   <head>
      <title><?php echo "Welcome to PHP-7 Tutorials";?></title>      
   </head>
   <body>
<?php
$array = [10,20,30];
foreach ($array as &$val) {
	var_dump($val);
	$array[2] = 99;
	$array[3] = 40;
}
?> 
   </body>
</html>

Пояснение кода

  • Мы объявляем массив из трех элементов [10, 20, 30];
  • Затем используем foreach для перебора массива, и внутри цикла выводим информацию о переменной с помощью функции var_dump;
  • Внутри этой функции мы использовали текущее значение связанного указателя для отображения значений массива;
  • Во время перебора массива с помощью foreach мы обновляем значение второго элемента с 30 на 99;
  • И в конце во время перебора массива с помощью PHP foreach мы добавляем новый элемент (40) с индексом 3.

Результат

Когда мы выполняем этот код PHP 7 на сервере, foreach выводит обновленное значение элемента с индексом 2, а также значение добавленного элемента с индексом 3, как показано ниже. Это демонстрирует улучшенное поведение foreach при переборе массива:

Результат
  • Перебор (Traversable) объектов: В PHP 7 перебор непроходимых объектов имеет то же поведение, что и перебор массивов с помощью by-reference. Данное улучшенное поведение характеризуется тем, что оператор имеет возможность отображать изменения, внесенные во время перебора массива по ссылке. Это применимо и к непроходимым объектам, а также во время добавления или удаления свойств объектов.

Чтобы лучше понять это, рассмотрим следующий пример:

<html>
   <head>
      <title><?php echo "Welcome to PHP-7 Tutorials";?></title>      
   </head>
   <body>
<?php
$inputArray = array(10, 20, 30);
$myobject = (object)$inputArray;
 
if ( !($inputArray instanceof Traversable) ) {
	print "inputArray is NOT Traversable";
}
if ( !($myobject instanceof Traversable) ) {
	print("<br />");
	print "myobject is NOT Traversable";
}
print("<br />Inside Array Iteration<br />");
foreach ($inputArray as &$val) {
	print $val;
	$inputArray[3] = 40;
	print("<br />");
}
print("<br />Inside Object Traversing<br />");
foreach ($myobject as &$val) {
	print $val;
	print("<br />");
}
?> 
   </body>
</html>

Пояснение кода:

  • Мы объявляем массив, который содержит 3 элемента и непроходимый объект;
  • Далее мы проверяем массив и непроходимый объект на невозможность прохождения;
  • Затем перебираем массив циклом foreach PHP через by-reference. Здесь мы добавляем значение 40 для элемента массива с индексом 3;
  • Перебираем непроходимый объект с помощью foreach через by-reference.

Результат

Когда мы выполняем код PHP 7 на сервере, поведение foreach для массивов и непроходимых объектов схоже;

Результат

Скачать исходный код

Заключение

В этой статье мы рассмотрели изменения, которые были внесены в foreach в РНР 7, а также привели ряд практических примеров для лучшего понимания.

Вадим Дворниковавтор-переводчик статьи «Learn How to do Changes to Foreach Statement in PHP 7»