How foreach Actually Works in PHP: Anatomy of a Loop

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: foreach — Not Just Syntactic Sugar

\n\n

Every PHP developer, from beginner to guru, uses foreach almost daily. It seems so simple and clear: "iterate over each element of the array." But have you ever asked yourself: how exactly does PHP do this? Why does the same foreach behave differently with arrays and objects? Why does modifying an array inside a loop sometimes lead to unexpected results?

\n\n

The question "How does PHP 'foreach' actually work?" on Stack Overflow has gathered tens of thousands of views and hundreds of votes. This is no coincidence: beneath this seemingly simple operator lies a complex and elegant mechanism. Today, we will look into the very heart of PHP and break down the anatomy of the foreach loop step by step.

\n\n

By the end of this article, you will not only understand how foreach works but also learn to avoid common mistakes that even experienced programmers encounter. Let's go!

\n\n

Chapter 1: foreach and the Internal Array Pointer

\n\n

When PHP encounters the construct foreach ($array as $value), it doesn't just "go through the indices." The underlying mechanism relies on the internal array pointer. This is an invisible "arrow" that points to the current element.

\n\n

Here is how this process looks step by step:

\n\n
    \n
  1. Reset the pointer. PHP calls reset($array) — the pointer moves to the first element.
  2. \n
  3. Read the key and value. The current element of the array is taken.
  4. \n
  5. Assignment. The value is copied into the variable $value (if there is no &).
  6. \n
  7. Advance the pointer. PHP moves the pointer to the next element.
  8. \n
  9. Repeat. Steps 2-4 are executed until the pointer reaches the end of the array.
  10. \n
\n\n

However, there is an important nuance: PHP creates a copy of the array before starting the iteration! Let's figure out why this is needed.

\n\n

Example: Resetting the Pointer Inside the Loop

\n\n
<?php\n$array = [10, 20, 30];\n\nforeach ($array as $value) {\n    echo "$value\\n";\n    // Attempt to reset the pointer\n    reset($array);\n}\n// Output: 10, 20, 30 — reset did not affect foreach\n?>
\n\n

Why didn't reset() work? Because foreach operates on a copy of the internal pointer, not the original. This is done intentionally so that modifying the array inside the loop does not break the iteration.

\n\n

Chapter 2: foreach by Value vs by Reference

\n\n

The most common source of confusion is the difference between foreach ($array as $value) and foreach ($array as &$value). Let's break it down clearly.

\n\n

foreach by Value: Copying at Each Step

\n\n

When you write foreach ($array as $value), PHP copies the current value of the array into the variable $value at each iteration. This means that modifying $value does not affect the original array.

\n\n
<?php\n$array = [1, 2, 3];\nforeach ($array as $value) {\n    $value *= 2; // Modifying the copy\n}\nprint_r($array);\n// Output: [1, 2, 3] — the array has not changed\n?>
\n\n

Pros: Safe, the original data is not corrupted.
\nCons: If the array elements are large objects, copying can be costly. Although PHP uses copy-on-write, for arrays with objects, only the identifiers (handles) are copied, not the objects themselves.

\n\n

foreach by Reference: Working with the Original

\n\n

The syntax foreach ($array as &$value) makes PHP pass a reference to the element, not a copy. Now $value is an alias for the array element.

\n\n
<?php\n$array = [1, 2, 3];\nforeach ($array as &$value) {\n    $value *=                

Blogs

Book Recommendations