Be wary of reference loops in PHP
The little bugger, a result of being overly clever, cost me an hour of debugging. Don't repeat my mistakes, clear your loops!
A while ago I refactored a piece of code that set some default values in an array. This is a simplified version of the original code:
foreach ($list as $key => $item) {
if (!isset($item["created"])) {
$list[$key]["created"] = time();
}
}
return $list;
}
As the loop worked quite a number of indexes with various stuff, I thought it would be a bit more readable if we ditched the array-lookup and used a by-reference-loop instead:
foreach ($list as $key => &$item) {
if (!isset($item["created"])) {
$item["created"] = time();
}
}
return $list;
}
All tests passed, the code got a bit more readable, everything was fine. Right up to the point someone added some more code to the function:
foreach ($list as $key => &$item) {
if (!isset($item["created"])) {
$item["created"] = time();
}
}
foreach ($matching as $match) {
$item = $match->referencing;
$list[$item->id]['references'][] = $foo;
}
return $list;
}
What happened? The short story is, the second loop is overwriting the last item of $list
in every iteration. That is because $item
is still a reference to the last element of the array $list
. Fortunately it's a rather easy fix.
Always unset()
a reference loop:
The author does not allow comments to this entry
Comments
Display comments as Linear | Threaded