PHP Foreach Loops
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 |
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
?>
$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:
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]
?>
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!
Enjoying these tutorials?