4

As I understand, when you pass a variable to a function, and if you don't use reference sign (&) , it means any changes inside your function will not affect to your variable outside the function. In other words, it means the compiler will make a copy of the outside variable to use inside function, doesn't it?

But when I run these testing code, it does not happen like that. Can anyone explain me what I miss here? Thank you

My test code: the expected result should be 3, but it becomes 1?

function test($arr2) {
    foreach($arr2 as &$item) {
        $item = 1;
    }
}
$arr = array(2);

foreach($arr as &$item2) {
    $item2 = 3;
}

test($arr); 
print_r($arr);
2
  • foreach($arr2 as &$item) { remove & from $item Commented Jul 8, 2015 at 5:53
  • possible duplicate of foreach loop and reference of &$value Commented Jul 9, 2015 at 0:04

3 Answers 3

2

This issue has been solved a few times before you've asked this (#1). The issue is due to the fact that:

Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

Reference: PHP foreach()

You need to unset the last $item2 after your foreach:

foreach ($arr as &$item2) {
    $item2 = 3;
}
unset($item2);
Sign up to request clarification or add additional context in comments.

3 Comments

yes, by unset($item2); we can solve the issue here or we can do some other ways. But I wonder why $item2 affects into test(), although I don't pass it into test(), or pass reference of $arr?
@TranHuynh Because your test is picking up that last "referenced" $item when you run it on the $arr
thanks Daren, actually I am quite confused at this point. when I pass $arr into test() . without reference, in test() it is called $arr2 => so $arr2 and $arr are independent to each other, right? It means $arr and $arr2 are 2 different variables. but why the last reference of $arr (called $item2, outside test()) can be effected by reference of $arr2 (called $item, inside test())?
0

This is quite interesting, it seems like the behavior of array are the same as objects in php in which new array still holds the copy of the members identifier (which points to the same value as the array it was copied from).

As of PHP 5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

PHP Manual - Objects and references

Comments

-1

Even though you are not passing $arr as Reference variable, you are still accessing $arr elements as References in function test(). So anything that changes in function will effect outside function too.

If you are looking to change $arr ( which has been passed as $arr2 in test function ) only in test function, then remove &from $item

1 Comment

it's not simple like that. If I don't run these line: foreach($arr as &$item2) { $item2 = 3; } I will be able to continue using &$item inside test() and the $arr value is not changed (as expected). Why is that? :)

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.