(PHP 4, PHP 5, PHP 7)

The foreach construct provides an easy way to iterate over arrays. foreach works only on arrays and objects, and will issue an error when you try to use it on a variable with a different data type or an uninitialized variable. There are two syntaxes:

foreach (array_expression as $value) statement foreach (array_expression as $key => $value) statement

The first form loops over the array given by array_expression . On each iteration, the value of the current element is assigned to $value and the internal array pointer is advanced by one (so on the next iteration, you"ll be looking at the next element).

The second form will additionally assign the current element"s key to the $key variable on each iteration.

In PHP 5, when foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.

As foreach relies on the internal array pointer in PHP 5, changing it within the loop may lead to unexpected behavior.

In PHP 7, foreach does not use the internal array pointer.

In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference .

$arr = array(1 , 2 , 3 , 4 );
foreach ($arr as & $value ) {
$value = $value * 2 ;
}
unset($value ); // break the reference with the last element
?>

Warning

Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset() . Otherwise you will experience the following behavior:

$arr = array(1 , 2 , 3 , 4 );
foreach ($arr as & $value ) {
$value = $value * 2 ;
}
// $arr is now array(2, 4, 6, 8)

// without an unset($value), $value is still a reference to the last item: $arr

Foreach ($arr as $key => $value ) {
// $arr will be updated with each value from $arr...
echo " { $key } => { $value } " ;
print_r ($arr );
}
// ...until ultimately the second-to-last value is copied onto the last value

// output:
// 0 => 2 Array ( => 2, => 4, => 6, => 2)
// 1 => 4 Array ( => 2, => 4, => 6, => 4)
// 2 => 6 Array ( => 2, => 4, => 6, => 6)
// 3 => 6 Array ( => 2, => 4, => 6, => 6)
?>

Before PHP 5.5.0, referencing $value is only possible if the iterated array can be referenced (i.e. if it is a variable). The following code works only as of PHP 5.5.0:

foreach (array(1 , 2 , 3 , 4 ) as & $value ) {
$value = $value * 2 ;
}
?>

foreach does not support the ability to suppress error messages using "@".

Some more examples to demonstrate usage:

/* foreach example 1: value only */

$a = array(1 , 2 , 3 , 17 );

foreach ($a as $v ) {
echo "Current value of \$a: $v .\n" ;
}

/* foreach example 2: value (with its manual access notation printed for illustration) */

$a = array(1 , 2 , 3 , 17 );

$i = 0 ; /* for illustrative purposes only */

Foreach ($a as $v ) {
echo "\$a[ $i ] => $v .\n" ;
$i ++;
}

/* foreach example 3: key and value */

$a = array(
"one" => 1 ,
"two" => 2 ,
"three" => 3 ,
"seventeen" => 17
);

foreach ($a as $k => $v ) {
echo "\$a[ $k ] => $v .\n" ;
}

/* foreach example 4: multi-dimensional arrays */
$a = array();
$a [ 0 ][ 0 ] = "a" ;
$a [ 0 ][ 1 ] = "b" ;
$a [ 1 ][ 0 ] = "y" ;
$a [ 1 ][ 1 ] = "z" ;

foreach ($a as $v1 ) {
foreach ($v1 as $v2 ) {
echo " $v2 \n" ;
}
}

/* foreach example 5: dynamic arrays */

Foreach (array(1 , 2 , 3 , 4 , 5 ) as $v ) {
echo " $v \n" ;
}
?>

Unpacking nested arrays with list()

(PHP 5 >= 5.5.0, PHP 7)

PHP 5.5 added the ability to iterate over an array of arrays and unpack the nested array into loop variables by providing a list() as the value.

$array = [
[ 1 , 2 ],
[ 3 , 4 ],
];

foreach ($array as list($a , $b )) {
// $a contains the first element of the nested array,
// and $b contains the second element.
echo "A: $a ; B: $b \n" ;
}
?>

A: 1; B: 2 A: 3; B: 4

You can provide fewer elements in the list() than there are in the nested array, in which case the leftover array values will be ignored:

A notice will be generated if there aren"t enough array elements to fill the list() :

$array = [
[ 1 , 2 ],
[ 3 , 4 ],
];

foreach ($array as list($a , $b , $c )) {
echo "A: $a ; B: $b ; C: $c \n" ;
}
?>

The above example will output:

Notice: Undefined offset: 2 in example.php on line 7 A: 1; B: 2; C: Notice: Undefined offset: 2 in example.php on line 7 A: 3; B: 4; C:

Changelog

Version Description
7.0.0 foreach does not use the internal array pointer anymore.
5.5.0 Referencing of $value is supported for expressions. Formerly, only variables have been supported.
5.5.0 Unpacking nested arrays with list() is supported.

9 years ago

For those who"d like to traverse an array including just added elements (within this very foreach), here"s a workaround:

$values = array(1 => "a" , 2 => "b" , 3 => "c" );
while (list($key , $value ) = each ($values )) {
echo " $key => $value \r\n" ;
if ($key == 3 ) {
$values [ 4 ] = "d" ;
}
if ($key == 4 ) {
$values [ 5 ] = "e" ;
}
}
?>
the code above will output:

1 => a
2 => b
3 => c
4 => d
5 => e

6 years ago

I want to add some inline comments to dtowell"s piece of code about the iteration by reference:

$a = array("abe" , "ben" , "cam" );

foreach ($a as $k =>& $n )
$n = strtoupper ($n );

# At the end of this cycle the variable $n refers to the same memory as $a
# So when the second "foreach" assigns a value to $n:

Foreach ($a as $k => $n ) // notice NO reference here!
echo " $n \n" ;

# it is also modifying $a .
# So on the three repetitions of the second "foreach" the array will look like:
# 1. ("abe","ben","abe") - assigned the value of the first element to the last element
# 2. ("abe","ben","ben") - assigned the value of the second element to the last element
# 3. ("abe","ben","ben") - assigned the value of the third element to itself

Print_r ($a );
?>

4 years ago

Modifying array while foreach"ing it(yeah, such slime code;-)
if elements were added on last iteration or into array with 1 element, then added elements wont be iterated as foreach checks for pointer before iteration cycle
so it just quit and added elements wont be treated

2 years ago

I want just to mention that John is not entirely true.

Simple field test:

$m = microtime(1); $array = range(1,1000000); foreach ($array as &$i) { $i = 4; } echo microtime(1) - $m;

Result: 0.21731400489807

$m = microtime(1); $array = range(1,1000000); foreach ($array as $k => $i) { $array[$k] = 4; } echo microtime(1) - $m;

Result: 0.51596283912659

PHP Version: PHP 5.6.30 (cli) (built: Jan 18 2017 19:47:36)

Conclusion: Working with reference, although a bit dangerous is >2 times faster. You just need to know well what are you doing.

Best of luck and happy coding all

5 years ago

Foreach by reference internally deleted and created a new reference in each iteration, so it is not possible to directly use this value as a variable parameter values​​, look at the following example where the problem is observed and a possible solution:

class test
{
private $a = false ;
private $r = null ;
public function show (& $v )
{
if(! $this -> a )
{
$this -> a = true ;
$this -> r = & $v ;
}
var_dump ($this -> r );
}
public function reset ()
{
$this -> a = false ;
}
}

$t = new test ();

$a = array(array(1 , 2 ),array(3 , 4 ),array(5 , 6 ));
foreach($a as & $p )
$t -> show ($p );

/* Output obtain:
array (size=2)
0 => int 1
1 => int 2
array (size=2)
0 => int 1
1 => int 2
array (size=2)
0 => int 1
1 => int 2
*/

$t -> reset ();
foreach($a as $p )
{
$b = & $p ;
$t -> show ($b );
}

/* Output obtain:
array (size=2)
0 => int 1
1 => int 2
array (size=2)
0 => int 3
1 => int 4
array (size=2)
0 => int 5
1 => int 6
*/

4 years ago

String keys of associative arrays, for which is_numeric() is true and which can be type-juggled to an int will be cast to an int! If the key is on the other hand a string that can be type-juggled into a float, it will stay a string. (Observed on PHP 7.0.0RC8)

$arr = array();
$arr [ 0 ] = "zero" ; // will stay an int
$arr [ "1" ] = "one" ; // will be cast to an int !
$arr [ "two" ] = "2" ; // will stay a string
$arr [ "3.5" ] = "threeandahalf" ; // will stay a string

Foreach($arr as $key => $value ) {
var_dump ($key );
}
?>

The output will be

int(0)
int(1)
string(3) "two"
string(3) "3.5"

2 years ago

Foreach retains the state of internal defined variable:

/**
Result for this array is:
Hello World
Hello World
Hello World
*/
$arr = [ "a" , "b" , "c" ];
$title = "" ;
foreach ($arr as $r ) {
if ($r == "a" ) {
$title = "Hello World" ;
}
echo $title . "
" ;
}
?>

in this case, all we need to do is to add an else statement:
$arr = [ "a" , "b" , "c" ];
$title = "" ;
/**
This prints:
Hello World
*/
foreach ($arr as $r ) {
if ($r == "a" ) {
$title = "Hello World" ;
} else {
$title = "" ;
}
echo $title . "
" ;
}
?>

8 years ago

$d3 = array("a" =>array("b" => "c" ));
foreach($d3 [ "a" ] as & $v4 ){}
foreach($d3 as $v4 ){}
var_dump ($d3 );
?>
will get something look like this:
array(1) {
["a"]=>
array(1) {
["b"]=>
&array(1) {
["b"]=>
*RECURSION*
}
}
}
then you try to walk some data with this array.
the script run out of memory and connect reset by peer

the document says:
Warning
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

so what I learn is that NEVER ignore """Warning""" in document....

4 years ago

Just a simple strange behavior I have ran into:

If you accidentally put a semicolon after the foreach statement, you get no errors, but the loop will only run on the last element of the array:
$array = array(1 , 2 , 3 );
foreach ($array as $key );
{
echo $key ;
}
// output: 3
?>

Correctly:
$array = array(1 , 2 , 3 );
foreach ($array as $key )
{
echo $key ;
}
// output: 123
?>

It took me a while to find that semicolon.

Цикл PHP foreach можно использовать следующим образом:

foreach($array_name as $value){ //код, который должен выполняться }

foreach($array_name as $key =>$value){ // //код, который должен выполняться }

Пример использования цикла foreach с числовым массивом

В этом примере мы создадим массив из пяти элементов с числовыми значениями. После этого цикл PHP foreach будет использован для выполнения итерации этого массива. Внутри цикла foreach мы использовали echo , чтобы вывести значения массива:

Посмотреть демо-версию и код

Пример с ключами и значениями массива

В этом примере описан другой способ использования цикла foreach PHP . Для этого мы создали ассоциативный массив из трех элементов. В него входят имена сотрудников (в качестве ключей ) и суммы заработной платы (в качестве значений ):

Посмотреть демо-версию и код

Пример изменения значения элемента массива в цикле foreach

Также можно c помощью PHP array foreach можно изменять значения элементов массива. Для этого используется «& » перед «$ » для переменной значения. Например:

&$value_of_element

Значение будет изменено. Чтобы вам было понятнее, рассмотрим следующий пример.

В этом примере мы создали числовой массив из пяти элементов. После этого использовали цикл foreach для отображения значений элементов.

Затем создали еще один цикл foreach , где перед $value_of_element добавляется «& «. Внутри фигурных скобок присваиваем новые значения элементам массива.

Чтобы увидеть разницу до и после присвоения новых значений, массив отображается с помощью функции print_r() .

Посмотреть демо-версию и код

Для чего используется цикл PHP foreach?

Цикл PHP foreach используется для работы с массивом. Он перебирает каждый его элемент.

Также можно использовать для работы с массивами цикл for . Например, используя свойство length , чтобы получить длину массива, а затем применить его в качестве оператора max . Но foreach делает это проще, так как он предназначен для работы с массивами.

Если вы работаете с MySQL , то для этого данный цикл подходит еще больше. Например, можно выбрать несколько строк из таблицы БД и передать их в массив. После этого, используя цикл foreach , перебрать все элементы массива с выполнением какого-либо действия.

Обратите внимание, что можно использовать цикл foreach с массивом или только с объектом.

Применение цикла foreach

В PHP существует два способа использования цикла foreach PHP. Оба описаны ниже.

  • Синтаксис первого метода использования:

foreach($array_name as $value){ echo $value }

При этом нужно указать имя массива, а затем переменную $value .

Для каждой итерации значение текущего элемента присваивается переменной $value . После завершения итерации переменной присваивается значение следующего элемента. И так до тех пор, пока все элементы массива не будут перебраны.

  • Синтаксис второго метода (PHP foreach as key value ):

Это подходит для ассоциативных массивов, в которых используются пары ключ / значение.

Во время выполнения каждой итерации значение текущего элемента будет присвоено переменной $value_of_element. Кроме этого ключ элемента присваивается переменной $key_of_element.

Если вы работаете с числовыми массивами, то можно использовать первый метод, в котором не нужны ключи элементов.

Данная публикация представляет собой перевод статьи «PHP foreach loop 2 ways to use it » , подготовленной дружной командой проекта

Часто нужно пройти по всем элементам массива PHP и провести какую-нибудь операцию над каждым элементом. Например, вы можете вывести каждое значение в таблицу HTML или задать каждому элементу новое значение.

В данном уроке мы рассмотрим конструкцию foreach при организации цикла по индексированным и ассоциированным массивам.

Цикл по значениям элементов

Самый простой случай использования foreach - это организация цикла по значениям в индексированном массиве. Основной синтаксис:

Foreach ($array as $value) { // Делаем что-нибудь с $value } // Здесь код выполняется после завершения цикла

Например, следующий скрипт проходит по списку режисеров в индексированном массиве и выводит имя каждого:

$directors = array("Alfred Hitchcock", "Stanley Kubrick", "Martin Scorsese", "Fritz Lang"); foreach ($directors as $director) { echo $director . "
"; }

Выше приведенный код выведет:

Alfred Hitchcock Stanley Kubrick Martin Scorsese Fritz Lang

Цикл по ключам и значениям

А что насчет ассоциированных массивов? При использовании такого типа массивов часто нужно иметь доступ к ключу каждого элемента, так же как и к его значению. Конструкция foreach имеет способ решить поставленную задачу:

Foreach ($array as $key => $value) { // Делаем что-нибудь с $key и/или с $value } // Здесь код выполняется после завершения цикла

Пример организации цикла по ассоциированному массиву с информацией о кинофильмах, выводит ключ каждого элемента и его значение в HTML списке определений:

$movie = array("title" => "Rear Window", "director" => "Alfred Hitchcock", "year" => 1954, "minutes" => 112); echo "

"; foreach ($movie as $key => $value) { echo "
$key:
"; echo "
$value
"; } echo "
";

Данный скрипт при выполнении выведет:

Title: Rear Window director: Alfred Hitchcock year: 1954 minutes: 112

Изменение значения элемента

А как обстоит дело с изменением значения элемента при проходе цикла? Вы можете попробовать такой код:

Foreach ($myArray as $value) { $value = 123; }

Однако, если запустить его на выполнение, то вы обнаружите, что значения в массиве не изменяются . Причина заключается в том, что foreach работает с копией значений массива, а не с оригиналом. Таким образом оригинальный массив остается нетронутым.

Для изменения значений массива вам нужна ссылка на значение. Для этого нужно поставить знак & перед переменной значения в конструкции foreach:

Foreach ($myArray as &$value) { $value = 123; }

Например, следующий скрипт проходит циклом каждый элемент (имя режиссера) в массиве $directors , и использует функцию PHP explode() и конструкцию list для перемены мест имени и фамилии:

$directors = array("Alfred Hitchcock", "Stanley Kubrick", "Martin Scorsese", "Fritz Lang"); // Изменяем формат имени для каждого элемента foreach ($directors as &$director) { list($firstName, $lastName) = explode(" ", $director); $director = "$lastName, $firstName"; } unset($director); // Выводим конечный результат foreach ($directors as $director) { echo $director . "
"; }

Скрипт выведет:

Hitchcock, Alfred Kubrick, Stanley Scorsese, Martin Lang, Fritz

Отметим, что скрипт вызывает функцию unset() для удаления переменной $director после завершения первого цикла. Это хорошая практика, если вы планируете использовать переменную позже в скрипте в другом контексте.

Если не удалять ссылку, то есть риск при дальнейшем выполнении кода случайной ссылки на последний элемент в массиве ("Lang, Fritz"), если далее использовать переменную $director , что приведет к непредвиденным последствиям!

Резюме

В данном уроке мы рассмотрели, как использовать конструкцию PHP foreach для организации цикла по элементам массива. Были рассмотрены вопросы:

  • Как организовать цикл по элементам массива
  • Как получить доступ к ключу и значению каждого элемента
  • Как использовать ссылку для изменения значений при проходе цикла

Циклы do while и foreach

Цикл do. . . while

Цикл do...while в C# - это версия while с постпроверкой условия. Это значит, что условие цикла проверяется после выполнения тела цикла. Следовательно, циклы do...while удобны в тех ситуациях, когда блок операторов должен быть выполнен как минимум однажды. Ниже приведена общая форма оператора цикла do-while:

do { операторы; } while (условие);

При наличии лишь одного оператора фигурные скобки в данной форме записи необязательны. Тем не менее они зачастую используются для того, чтобы сделать конструкцию do-while более удобочитаемой и не путать ее с конструкцией цикла while. Цикл do-while выполняется до тех пор, пока условное выражение истинно. В качестве примера использования цикла do-while можно привести следующую программу, расчитывающую факториал числа:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { try { // Вычисляем факториал числа int i, result = 1, num = 1; Console.WriteLine("Введите число:"); i = int.Parse(Console.ReadLine()); Console.Write("\n\nФакториал {0} = ", i); do { result *= num; num++; } while (num

Цикл foreach

Цикл foreach служит для циклического обращения к элементам коллекции , представляющей собой группу объектов. В C# определено несколько видов коллекций, каждая из которых является массивом. Ниже приведена общая форма оператора цикла foreach:

foreach (тип имя_переменной_цикла in коллекция) оператор;

Здесь тип имя_переменной_цикла обозначает тип и имя переменной управления циклом, которая получает значение следующего элемента коллекции на каждом шаге выполнения цикла foreach. А коллекция обозначает циклически опрашиваемую коллекцию, которая здесь и далее представляет собой массив. Следовательно, тип переменной цикла должен соответствовать типу элемента массива. Кроме того, тип может обозначаться ключевым словом var. В этом случае компилятор определяет тип переменной цикла, исходя из типа элемента массива. Это может оказаться полезным для работы с определенного рода запросами. Но, как правило, тип указывается явным образом.

Оператор цикла foreach действует следующим образом. Когда цикл начинается, первый элемент массива выбирается и присваивается переменной цикла. На каждом последующем шаге итерации выбирается следующий элемент массива, который сохраняется в переменной цикла. Цикл завершается, когда все элементы массива окажутся выбранными.

Цикл foreach позволяет проходить по каждому элементу коллекции (объект, представляющий список других объектов). Формально для того, чтобы нечто можно было рассматривать как коллекцию, это нечто должно поддерживать интерфейс IEnumerable . Примерами коллекций могут служить массивы C#, классы коллекций из пространства имен System.Collection, а также пользовательские классы коллекций.




Close