Web Analytics

PHP Foreach Loops

Beginner~30 min read

The foreach loop is PHP's most elegant way to iterate arrays. It automatically handles array traversal without needing counters or indices - just loop through each element directly!

Foreach Syntax

There are two forms of foreach - with values only, or with keys and values:

<?php
// Values only
foreach ($array as $value) {
    // Use $value
}

// Keys and values
foreach ($array as $key => $value) {
    // Use $key and $value
}
?>
Syntax Use Case
$array as $value When you only need the values
$array as $key => $value When you need both keys and values
Output
Click Run to execute your code

Indexed Arrays

For simple indexed arrays, you usually just need the values:

<?php
$fruits = ["Apple", "Banana", "Cherry"];

// Simple iteration
foreach ($fruits as $fruit) {
    echo "I like $fruit\n";
}

// With index (key)
foreach ($fruits as $index => $fruit) {
    $position = $index + 1;
    echo "$position. $fruit\n";
}
// Output:
// 1. Apple
// 2. Banana
// 3. Cherry
?>

Associative Arrays

For associative arrays, the key-value syntax is essential:

<?php
$user = [
    "name" => "John",
    "email" => "[email protected]",
    "role" => "admin"
];

foreach ($user as $field => $value) {
    echo ucfirst($field) . ": $value\n";
}
// Output:
// Name: John
// Email: [email protected]
// Role: admin
?>
Naming Convention: Choose meaningful variable names that describe what you're iterating. Use singular for the value ($user in $users) and the actual property name for keys ($field, $id, $name).

Nested Arrays

Foreach handles nested arrays elegantly:

<?php
$products = [
    ["name" => "Laptop", "price" => 999.99],
    ["name" => "Mouse", "price" => 29.99],
    ["name" => "Keyboard", "price" => 79.99]
];

foreach ($products as $product) {
    echo "{$product['name']}: ${$product['price']}\n";
}

// With nested foreach
$categories = [
    "Electronics" => ["TV", "Radio", "Phone"],
    "Clothing" => ["Shirt", "Pants", "Hat"]
];

foreach ($categories as $category => $items) {
    echo "\n$category:\n";
    foreach ($items as $item) {
        echo "  - $item\n";
    }
}
?>

Modifying Values by Reference

Use & to modify array elements in place:

Output
Click Run to execute your code

Reference Syntax

<?php
$numbers = [1, 2, 3, 4, 5];

// Without reference - original unchanged
foreach ($numbers as $num) {
    $num *= 2;  // Modifies copy only
}
// $numbers is still [1, 2, 3, 4, 5]

// With reference - modifies original
foreach ($numbers as &$num) {
    $num *= 2;  // Modifies actual array element
}
unset($num);  // CRITICAL: Remove reference!
// $numbers is now [2, 4, 6, 8, 10]
?>
Critical: Always call unset($var) after a reference foreach loop! The reference variable remains linked to the last array element, which can cause subtle bugs if you reuse the variable name later.

Foreach vs For Loop

Feature foreach for
Best for Arrays and objects Known iteration count
Index access Built-in with $key Manual with $i
Associative arrays Native support Not practical
Readability More readable More verbose
Skip by index Not easy Easy with $i += 2
<?php
$colors = ["red", "green", "blue"];

// Foreach (recommended for arrays)
foreach ($colors as $color) {
    echo "$color ";
}

// For loop equivalent (verbose)
for ($i = 0; $i < count($colors); $i++) {
    echo $colors[$i] . " ";
}
?>

Alternative Syntax

For templates mixing PHP and HTML:

<?php $users = [
    ["name" => "Alice", "active" => true],
    ["name" => "Bob", "active" => false]
]; ?>

<ul>
<?php foreach ($users as $user): ?>
    <li class="<?= $user['active'] ? 'active' : 'inactive' ?>">
        <?= htmlspecialchars($user['name']) ?>
    </li>
<?php endforeach; ?>
</ul>

Common Mistakes

1. Forgetting unset() after reference

<?php
$arr = [1, 2, 3];

// ❌ WRONG: Missing unset()
foreach ($arr as &$val) {
    $val *= 2;
}
// $val still references $arr[2]!

$val = 100;  // Oops! Changes $arr[2] to 100!
print_r($arr);  // [2, 4, 100] - unexpected!

// ✅ CORRECT: Always unset
foreach ($arr as &$val) {
    $val *= 2;
}
unset($val);  // Break the reference
?>

2. Modifying array during iteration

<?php
$items = ["a", "b", "c", "d"];

// ❌ DANGEROUS: Adding elements while iterating
foreach ($items as $item) {
    if ($item === "b") {
        $items[] = "e";  // Don't do this!
    }
}

// ✅ SAFE: Build a new array instead
$newItems = [];
foreach ($items as $item) {
    $newItems[] = $item;
    if ($item === "b") {
        $newItems[] = "e";
    }
}
?>

3. Using wrong syntax for keys

<?php
$data = ["name" => "John", "age" => 30];

// ❌ WRONG: Only gets values
foreach ($data as $value) {
    // Can't access the key here!
}

// ✅ CORRECT: Get both key and value
foreach ($data as $key => $value) {
    echo "$key: $value\n";
}
?>

Exercise: Data Processor

Task: Process a list of products and calculate statistics.

Requirements:

  • Calculate total value of all products (price × quantity)
  • Find the most expensive product
  • Apply a 15% discount to products over $50
  • Display the results
Show Solution
<?php
$products = [
    ["name" => "Laptop", "price" => 999.99, "qty" => 2],
    ["name" => "Mouse", "price" => 29.99, "qty" => 10],
    ["name" => "Keyboard", "price" => 79.99, "qty" => 5],
    ["name" => "Monitor", "price" => 299.99, "qty" => 3]
];

$totalValue = 0;
$mostExpensive = null;
$highestPrice = 0;

// Process products
foreach ($products as &$product) {
    // Calculate line total
    $lineTotal = $product['price'] * $product['qty'];
    $totalValue += $lineTotal;

    // Track most expensive
    if ($product['price'] > $highestPrice) {
        $highestPrice = $product['price'];
        $mostExpensive = $product['name'];
    }

    // Apply discount to items over $50
    if ($product['price'] > 50) {
        $product['price'] *= 0.85;  // 15% off
        $product['discounted'] = true;
    }
}
unset($product);

echo "=== Product Report ===\n\n";
foreach ($products as $product) {
    $status = isset($product['discounted']) ? " (15% OFF!)" : "";
    printf("%-10s: $%7.2f x %d%s\n",
        $product['name'],
        $product['price'],
        $product['qty'],
        $status
    );
}

echo "\nTotal Inventory Value: $" . number_format($totalValue, 2) . "\n";
echo "Most Expensive Item: $mostExpensive\n";
?>

Summary

  • Basic: foreach ($arr as $val) - values only
  • Key-Value: foreach ($arr as $key => $val)
  • Reference: foreach ($arr as &$val) - modify in place
  • Always unset: Call unset($val) after reference loops
  • Best for: Arrays and objects of any structure
  • Readable: More intuitive than for loops for collections
  • Alternative: foreach: ... endforeach; for templates

What's Next?

You've learned all PHP loop types! Now let's master Loop Control with break and continue to precisely control loop execution!