One of the available loop control structures within PHP is called a foreach loop. A foreach loop is typically used for iterating over a associative ( key => value ) like container. This means array’s and objects can be iterated over within a foreach loop. However, when iterating over an object within the foreach loop you will be iterating over the object’s member variables. Since PHP 5, you are able to define and use iterator objects which are used to define custom iteration code.
Here are a couple of examples of a foreach loop and its construct:
$array = array(1, 2, 3, 4, 5);
foreach( $array as $value )
{
...
$object = new stdClass;
$object->variable = "Here is my variable";
foreach( $object as $key => $value )
{
/* $key = Member variable name
$value = Member variable's value. */
Note that within this second example I have used a standard class object (stdClass) to iterate over. However, there is a quirk using the foreach loop that a lot of people do not realize. The quirk is simple, the “value” variable assigned to contain the value at each offset during iteration will exist out of the foreach scope when the foreach loop has completed iteration. For example:
$array = array(1, 2, 3, 4, 5);
/* foreach( $array as $value ) could also have been used */
foreach( $array as $key => $value )
{
/* do operations here ... */
}
/* The value of $value if not unset()'ed immediately after
the foreach loop's scope, will be 5 as it is the last element iterated over. */
echo $value;
Okay, so you see now that there is this little quirk in the foreach loop. So to solve the problem simply invoke unset() on the $value variable immediately after the foreach’s closing brace. However, the above example is not so bad since the $value variable is not affecting the $array since values and key’s are copied (reassigned). But, if the foreach loop construct is defined by assigning the variable value by reference then things can get tricky. Here is an example:
$array = array(1, 2, 3, 4, 5);
foreach( $array as $key => &$value )
{
/* do operations here */
}
If you decide to assign the value as a reference, the $value variable out of the foreach scope will affect the array’s last element. Meaning if a new value is assigned to the value out of the foreach scope it will also reassign the value of the last element within the $array. Let’s take a look at an example:
$array = array(1, 2, 3, 4, 5);
foreach( $array as $key => &$value )
{
/* do operations here */
}
$value = 'Hello World';
/* Let's print they array to show the value of each element */
/* Output will be as follows:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => Hello World )
*/
print_r( $array );
You will see that this could result in some problems later on down the road. Therefore we must assure that unset() is performed immediately after the foreach’s closing brace. Here is a completed solution that solves the problem of referencing the last element after and out of the foreach scope.
$array = array(1, 2, 3, 4, 5);
foreach( $array as $key => &$value )
{
/* do operations here */
}
unset($value);
And now you have the knowledge of one major quirk about the foreach loop control structure available to be used within PHP. I look forward to hearing your comments and or suggestions regarding this.

Ran into this “bug” a couple of months ago. The PHP guys say it’s a feature, and there are many lengthy papers defending it.
You explain this quirky behaviour very well in this article.
Cheers
gav
Ya. I am not sure personally if I like the “feature” or not.
Do you by any chance have any of these lengthy papers and or articles defending it? I would love to read one or two of them to see the defense.
And thanks for the comment! Glad to see at least one person visiting and reading
Aaron
It is useful to try everything in practice anyway and I like that here it’s always possible to find something new.
Thanks for this one! I have just done piece of code with two FOREACH iterations one after another. The first one was that with reference. Half an hour I wondered why my last item always sets to value of first one
I can see a way to use the “quirk” to a programmers benefit: Say you always want to assign the last key of an array to a certain value and not have its order affected.
if (x < 'a dozen better ways') {
echo 'My defense isn't nearly enough for them NOT to add limited scope for associative variables';
}
else {
echo 'Meh.';
}