foreach Loop
To process all elements of an array or associative array in order, use the『foreach』statement. Unlike the『for』statement in『PHP』, no index management is required, making it straightforward to iterate over array elements.
Syntax
// Value only (works with both indexed and associative arrays)
foreach ($array as $value) {
// $value receives the value of each element
}
// Both key and value
foreach ($array as $key => $value) {
// $key receives the key (or numeric index), $value receives the value
}
// By reference (directly modifies values in the original array)
foreach ($array as &$value) {
// Modifying $value also changes the original array
}
unset($value); // Always call unset() after a by-reference loop to release the reference
Each Part of the Syntax
| Part | Description |
|---|---|
| $array | The array or associative array to iterate over. Objects can also be specified. |
| $value | The variable that receives the value of each element per iteration. The variable name is freely chosen. |
| $key => $value | Form that retrieves both key and value. For indexed arrays, $key receives 0, 1, 2, ... For associative arrays, it receives the string keys. |
| &$value | By reference. Modifying $value within the loop changes the original array. Always call unset() to release the reference after the loop. |
Sample Code
foreach_basic.php
<?php
// Iterate over the Steins;Gate character list with foreach
$members = ["岡部倫太郎", "椎名まゆり", "橋田至", "牧瀬紅莉栖", "阿万音鈴羽"];
// Basic pattern: value only
foreach ($members as $name) {
echo $name . ": member of Future Gadget Laboratory\n";
}
Running the code produces the following output:
php foreach_basic.php 岡部倫太郎: member of Future Gadget Laboratory 椎名まゆり: member of Future Gadget Laboratory 橋田至: member of Future Gadget Laboratory 牧瀬紅莉栖: member of Future Gadget Laboratory 阿万音鈴羽: member of Future Gadget Laboratory
foreach_key_value.php
<?php
// Iterate an associative array retrieving both key and value
// Steins;Gate character and lab member number mapping
$labMembers = [
"001" => "岡部倫太郎",
"002" => "椎名まゆり",
"003" => "橋田至",
"004" => "牧瀬紅莉栖",
"005" => "阿万音鈴羽",
"006" => "フェイリス・ニャンニャン",
"007" => "桐生萌郁",
"008" => "漆原るか",
];
// $key receives the lab member number, $name receives the character name
foreach ($labMembers as $number => $name) {
echo "Lab Member No." . $number . ": " . $name . "\n";
}
Running the code produces the following output:
php foreach_key_value.php Lab Member No.001: 岡部倫太郎 Lab Member No.002: 椎名まゆり Lab Member No.003: 橋田至 Lab Member No.004: 牧瀬紅莉栖 Lab Member No.005: 阿万音鈴羽 Lab Member No.006: フェイリス・ニャンニャン Lab Member No.007: 桐生萌郁 Lab Member No.008: 漆原るか
foreach_reference.php
<?php
// By reference (&$value): directly modify the original array values
$dMailMessages = [
"El Psy Kongroo",
"Divergence: 1.048596",
"Operation Altair",
];
echo "--- Before ---\n";
foreach ($dMailMessages as $message) {
echo $message . "\n";
}
// Writing &$message causes modifications in the loop to be reflected in the original array
foreach ($dMailMessages as &$message) {
$message = "[D-Mail] " . $message; // Directly rewrites the original array value
}
unset($message); // Release the reference after a by-reference loop
// Without this, $message keeps referencing the last element,
// which can cause unexpected overwrites later
echo "\n--- After ---\n";
foreach ($dMailMessages as $message) {
echo $message . "\n";
}
Running the code produces the following output:
php foreach_reference.php --- Before --- El Psy Kongroo Divergence: 1.048596 Operation Altair --- After --- [D-Mail] El Psy Kongroo [D-Mail] Divergence: 1.048596 [D-Mail] Operation Altair
foreach_nested.php
<?php
// Pattern for traversing nested arrays (multidimensional arrays)
// Managing Steins;Gate character information in associative arrays
$characters = [
[
"name" => "岡部倫太郎",
"alias" => "Hououin Kyouma",
"role" => "Lab leader",
],
[
"name" => "牧瀬紅莉栖",
"alias" => "Christina",
"role" => "Genius scientist",
],
[
"name" => "阿万音鈴羽",
"alias" => "Part-time warrior",
"role" => "Time traveler",
],
];
// Outer foreach retrieves each character's array
foreach ($characters as $index => $character) {
echo "--- Character " . ($index + 1) . " ---\n";
// Inner foreach traverses the character's keys and values
foreach ($character as $key => $value) {
echo $key . ": " . $value . "\n";
}
}
Running the code produces the following output:
php foreach_nested.php --- Character 1 --- name: 岡部倫太郎 alias: Hououin Kyouma role: Lab leader --- Character 2 --- name: 牧瀬紅莉栖 alias: Christina role: Genius scientist --- Character 3 --- name: 阿万音鈴羽 alias: Part-time warrior role: Time traveler
Common Mistakes
Forgetting unset() after a by-reference loop
After a by-reference (『&$value』) loop, if you forget to release the reference with unset(), using a variable with the same name later will overwrite the last element of the array.
ng_foreach_ref.php
<?php
$messages = ["El Psy Kongroo", "Divergence: 1.048596", "Operation Altair"];
foreach ($messages as &$message) {
$message = "[D-Mail] " . $message;
}
// unset($message) is forgotten
// This assignment overwrites the last element of the array
$message = "overwritten value";
foreach ($messages as $m) {
echo $m . "\n";
}
Running the code produces the following output:
php ng_foreach_ref.php [D-Mail] El Psy Kongroo [D-Mail] Divergence: 1.048596 overwritten value
Always release the reference with unset() after a by-reference loop.
ok_foreach_ref.php
<?php
$messages = ["El Psy Kongroo", "Divergence: 1.048596", "Operation Altair"];
foreach ($messages as &$message) {
$message = "[D-Mail] " . $message;
}
unset($message); // Release the reference
$message = "overwritten value"; // Does not affect the array
foreach ($messages as $m) {
echo $m . "\n";
}
Running the code produces the following output:
php ok_foreach_ref.php [D-Mail] El Psy Kongroo [D-Mail] Divergence: 1.048596 [D-Mail] Operation Altair
Expecting that elements added to an array inside a loop are traversed in that same loop
foreach uses a copy of the array at the start of traversal. Elements added to the array inside the loop are not processed in that current loop.
ng_foreach_add.php
<?php
$members = ["岡部倫太郎", "椎名まゆり"];
// "牧瀬紅莉栖" added during the loop is not processed in the current loop
foreach ($members as $name) {
echo $name . "\n";
if ($name === "椎名まゆり") {
$members[] = "牧瀬紅莉栖"; // Added but not output in this loop
}
}
echo "Final array state:\n";
foreach ($members as $name) {
echo $name . "\n";
}
Running the code produces the following output:
php ng_foreach_add.php 岡部倫太郎 椎名まゆり Final array state: 岡部倫太郎 椎名まゆり 牧瀬紅莉栖
If you also want to traverse added elements, combine while with array_shift(), or split into separate loops.
ok_foreach_add.php
<?php
$members = ["岡部倫太郎", "椎名まゆり"];
// When adding elements to traverse later, split into separate loops
$toAdd = [];
foreach ($members as $name) {
echo $name . "\n";
if ($name === "椎名まゆり") {
$toAdd[] = "牧瀬紅莉栖";
}
}
foreach ($toAdd as $name) {
echo $name . " (added)\n";
$members[] = $name;
}
Running the code produces the following output:
php ok_foreach_add.php 岡部倫太郎 椎名まゆり 牧瀬紅莉栖 (added)
Summary
The『foreach』statement is a loop construct for processing all elements of an array or associative array in order. Unlike the『for』statement, no counter variable or index management is needed; values and keys are received directly into variables, making it the standard choice for array traversal.
Using by-reference (『&$value』) lets you directly modify the original array values from inside the loop.However, even after the loop ends the variable keeps referencing the last element, so you must always release the reference with『unset($value)』immediately after the loop.Forgetting this can cause a bug where the end of the array is unintentionally overwritten when the same variable name is used later.
For multidimensional arrays, nest foreach loops. The common pattern is to retrieve each element (sub-array) in the outer loop, then traverse its keys and values in the inner loop. For array operations, see also『array_map() / array_filter()』and『for statement』.
If you find any errors or copyright issues, please contact us.