Reputation: 5524
I'm testing the performances/hitches for References over copies of an array. I have the following code:
function ScoreWords($Value){
$WordList = array(
"Amazing" => 1,
"Value" => 300,
"Elements" => 30,
"Another" => 0
);
if (array_key_exists($Value,$WordList)){
return $WordList[$Value];
}
}
$array = ["Value","Another",1,2,3,4];
echo implode(',', $array), "<br>";
foreach ($array as &$value) {
ScoreWords($value);
}
echo implode(',', $array), "<br>";
foreach ($array as $value) {
ScoreWords($value);
}
echo implode(',', $array), "<br>";
But it seems, the code pasted above works semi-fine. Output is:
Value,Another,1,2,3,4
Value,Another,1,2,3,4
Value,Another,1,2,3,3
I found this by mistake as imploding was not actually necessary, but this sparks the question. Why is there a duplicated value for the final print rather than the correct value of 4
? regardless of what the content of the array is. It seems to duplicate the second from last element as the last element?
Upvotes: 2
Views: 49
Reputation: 7552
The thing here is that you have to unset
the value when you pass it by reference:
foreach ($array as &$value) {
ScoreWords($value);
}
unset($value); // break the reference with the last element
Warning Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
Upvotes: 1
Reputation: 227270
What is happening is that after your 1st foreach
, $value
is a reference to the last element in the array. As that loop progressed it was a reference to each element, until finally stopping at the last one.
So, when the 2nd foreach
runs, $value
is still a reference. As that loop runs, it updates $value
, which in turn, updates the last element in the array.
When it gets to the last element, it was set to 3 from the previous loop iteration. So, that's why it's set to 3 at the end.
To fix this, unset($value);
after your first foreach
.
Upvotes: 3