9

this code produce an unexpected output:

$array=str_split("abcde");
foreach($array as &$item)
    echo $item;

echo "\n";
foreach($array as $item)
    echo $item;

output:

abcde
abcdd

if use &$item for second loop everything works fine.

I don't understand how this code would affect the content of $array. I could consider that an implicit unset($header) would delete the last row but where does the double dd comes from ?

1 Answer 1

12

This could help:


$array=str_split("abcde");
foreach($array as &$item) {
    echo $item;
}

var_dump($array);

echo "\n";
foreach($array as $item) {
    var_dump($array);
    echo $item;
}

As you can see after the last iteration $item refers to 4th element of $array (e).

After that you iterate over the array and change the 4th element to the current one. So after first iteration of the second loop it will be abcda, etc to abcdd. And in the last iteration you change 4th element to 4th, as d to d

After the first loop you should do unset($item); it is a common practice to unset reference variable as long as you don't need it anymore to prevent such confusions.

Sign up to request clarification or add additional context in comments.

5 Comments

thanks. Is there anyway to "detach" $item from 4th element after the first loop ?
@lenzai: unset($item); --- it is a common practice to unset reference variable as long as you don't need it anymore to prevent such confusions.
my mistake, i thought unsset($item would delete $array[4]. I guess I was wrong.
@lenzai: unset always destroys reference. If you have $a = 1; unset($a); it destroys the only one reference to 1 placed in memory. As long as there are no any other references - 1 is not accessible anymore with any variable name, so you treat it as "unset". So think of unset as just "some construct that breaks interconnection between variable name and memory, but doesn't modify memory"
In fact, the documentation of foreach (php.net/manual/en/control-structures.foreach.php) specifically talks about this: "Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset(). "

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.