foreach by reference leaves the last element bound

Iterating by reference is the standard way to modify an array in place. What almost nobody remembers is that the loop variable survives the loop, still bound to the final element — so the next foreach that reuses the name does not read into a fresh variable, it writes through a reference into the array you just finished.

$rows = array('ada', 'grace', 'edsger');

foreach ($rows as &$row) {
    $row = ucfirst($row);
}

// $row is still a reference to $rows[2]

foreach ($rows as $row) {
    // every pass assigns through that reference, into $rows[2]
}

print_r($rows);
// Array ( [0] => Ada [1] => Grace [2] => Grace )

The array ends up with its second-to-last element duplicated over the last one, which looks like a data problem rather than a language problem and gets debugged in the wrong place for an afternoon. unset($row) on the line after the closing brace is the whole fix, and putting it there rather than further down makes the pairing obvious to the next reader. The bug needs two loops sharing a variable name to appear, which is exactly why it survives review of the first loop and shows up months later when someone adds the second. Where the transformation is a plain function of the value, array_map() sidesteps the question entirely; the reference form is worth keeping when the array is large enough that a copy matters.