← Back to PHP Course | Chapter 4: Control Flow | Lesson 13 of 14

PHP foreach Loop

A foreach loop is like walking down a shelf and picking up each item one after another. It hands you every item in a list without you having to count positions.
Syntax
php
foreach ($array as $value) {
    // use $value
}

foreach ($array as $key => $value) {
    // use $key and $value
}

What is a foreach Loop?

The foreach loop is PHP's dedicated tool for walking through every element of an array without manually tracking an index.

Where a for loop needs you to manage a counter and bounds yourself, foreach hands you each value directly, which is why it's the loop PHP developers reach for first when the goal is simply "do this for every item."

Example: What is a foreach Loop?

php
<?php
// Declare `$fruits` as an array: `["apple", "banana", "cherry"]`
$fruits = ["apple", "banana", "cherry"];
// Loop over `$fruits`, binding each item to `$fruit`
foreach ($fruits as $fruit) {
    // Print `$fruit . "\n"` to the output
    echo $fruit . "\n";
}
?>

Looping With Keys and Values

Writing foreach ($array as $key => $value) gives you both the array key and its value on each pass, which matters enormously for associative arrays where the key carries real meaning — a username, a product ID, a config option name.

Without the => $value form you'd only see the values and lose that context entirely.

Example: Looping With Keys and Values

php
<?php
// Declare `$config` as an array: `["theme" => "dark", "lang" => "en"]`
$config = ["theme" => "dark", "lang" => "en"];
// Loop over `$config`, binding each item to `$key => $value`
foreach ($config as $key => $value) {
    // Print "$key: $value\n" to the output
    echo "$key: $value\n";
}
?>

Modifying Values by Reference

Adding an ampersand, foreach ($array as &$value), makes $value a reference into the original array rather than a copy, so changes you make inside the loop body actually update the array itself.

This is the only built-in way to modify array elements in place during a foreach pass.

Example: Modifying Values by Reference

php
<?php
// Declare `$numbers` as an array: `[1, 2, 3]`
$numbers = [1, 2, 3];
// Loop over `$numbers`, binding each item to `&$value`
foreach ($numbers as &$value) {
    $value *= 2;
}
// Remove `$value`
unset($value);
// Print a human-readable dump of `$numbers`
print_r($numbers);
?>

The Dangling Reference Pitfall

After a by-reference foreach finishes, $value still points at the array's last element — reusing that same variable name in a later, non-reference foreach can silently overwrite that last element with unrelated data.

The fix is a single unset($value); right after the reference loop ends, and skipping it is one of PHP's most common array bugs.

Example: The Dangling Reference Pitfall

php
<?php
$numbers = [1, 2, 3];
foreach ($numbers as &$value) {
    $value *= 2;
}
unset($value); // without this, the next foreach below would corrupt the last element
foreach ($numbers as $value) {
    echo $value . "\n";
}
?>

foreach With Nested and Multidimensional Arrays

Nesting one foreach inside another is the natural way to walk a multidimensional array, such as a list of associative arrays representing rows of data — the outer loop gives you each row, and an inner loop or direct key access reads that row's individual fields.

Example: foreach With Nested and Multidimensional Arrays

php
<?php
$rows = [
    ["name" => "Alice", "age" => 30],
    ["name" => "Bob", "age" => 25],
];
// Loop over `$rows`, binding each item to `$row`
foreach ($rows as $row) {
    // Print `$row["name"] . " is " . $row["age"] . "\n"` to the output
    echo $row["name"] . " is " . $row["age"] . "\n";
}
?>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Modifying $value inside foreach and expecting the array to change, when by default it is a copy; use &$value to modify in place.
  2. Leaving a by-reference foreach variable alive and reusing it in a later loop, which overwrites the array's last element.
  3. Modifying the array's keys or adding elements while looping over it, which gives unexpected results because foreach works on a copy by default.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.