foreach ($colors as $color) {
echo "I am the color $color<br>";
}
$foods = ['healthy' => 'Apples', 'bad' => 'Ice Cream'];
foreach ($foods as $key => $food) {
echo "Eating $food is $key";
}
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;
}
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
.