Using foreach
suggest changeDirect loop
foreach ($colors as $color) {
echo "I am the color $color<br>";
}
Loop with keys
$foods = ['healthy' => 'Apples', 'bad' => 'Ice Cream'];
foreach ($foods as $key => $food) {
echo "Eating $food is $key";
}
Loop by reference
In the foreach
loops in the above examples, modifying the value ($color
or $food
) directly doesn’t change its value in the array. The &
operator is required so that the value is a reference pointer to the element in the array.
$years = [2001, 2002, 3, 4];
foreach ($years as &$year) {
if ($year < 2000) $year += 2000;
}
This is similar to:
$years = [2001, 2002, 3, 4];
for($i = 0; $i < count($years); $i++) { // these two lines
$year = &$years[$i]; // are changed to foreach by reference
if($year < 2000) $year += 2000;
}
Concurrency
PHP arrays can be modified in any ways during iteration without concurrency problems (unlike e.g. Java List
s). If the array is iterated by reference, later iterations will be affected by changes to the array. Otherwise, the changes to the array will not affect later iterations (as if you are iterating a copy of the array instead). Compare looping by value:
$array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
foreach ($array as $key => $value) {
if ($key === 0) {
$array[6] = 17;
unset($array[4]);
}
echo "$key => $value\n";
}
Output:
0 => 1
2 => 3
4 => 5
6 => 7
But if the array is iterated with reference,
$array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
foreach ($array as $key => &$value) {
if ($key === 0) {
$array[6] = 17;
unset($array[4]);
}
echo "$key => $value\n";
}
Output:
0 => 1
2 => 3
6 => 17
The key-value set of 4 => 5
is no longer iterated, and 6 => 7
is changed to 6 => 17
.