Unexpected Behavior from foreach Reference

Last array element is unexpectedly duplicated after foreach with reference

Quick Answer

After a foreach loop using &$value, the reference variable still points to the last array element. Unset the reference after the loop or avoid using references.

Why This Happens

When you use foreach ($array as &$value), the $value variable remains a reference to the last element after the loop ends. If you then use $value in another loop or assignment, you are modifying the last element of the original array. This is one of PHP's most notorious gotchas.

The Problem

$numbers = [1, 2, 3];
foreach ($numbers as &$num) {
    $num *= 2;
}
foreach ($numbers as $num) {
    echo $num . ' '; // Outputs: 2 4 4 (not 2 4 6)
}

The Fix

$numbers = [1, 2, 3];
foreach ($numbers as &$num) {
    $num *= 2;
}
unset($num); // Always unset the reference!
foreach ($numbers as $num) {
    echo $num . ' '; // Outputs: 2 4 6
}

Step-by-Step Fix

  1. 1

    Find foreach reference loops

    Search for foreach statements that use &$variable. These are the potential source of the bug.

  2. 2

    Unset the reference

    Add unset($variable) immediately after every foreach loop that uses a reference to break the reference binding.

  3. 3

    Consider alternatives

    Use array_map() or array_walk() instead of foreach with references to avoid the reference pitfall entirely.

Got the actual stack trace?

Paste it into our free AI explainer to get the cause and the fix for your specific case — no signup, nothing to install.

Explain my error

Bugsly catches this automatically

Bugsly's AI analyzes this error pattern in real-time, explains what went wrong in plain English, and suggests the exact fix — before your users even report it.

Try Bugsly free