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);
Rowel
  • 115
  • 2
  • 11
Tran Huynh
  • 41
  • 3
  • `foreach($arr2 as &$item) {` remove `&` from `$item` – Tushar Jul 08 '15 at 05:53
  • possible duplicate of [foreach loop and reference of &$value](http://stackoverflow.com/questions/24902742/foreach-loop-and-reference-of-value) – Darren Jul 09 '15 at 00:04

3 Answers3

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);
Community
  • 1
  • 1
Darren
  • 13,050
  • 4
  • 41
  • 79
  • 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? – Tran Huynh Jul 08 '15 at 07:44
  • @TranHuynh Because your test is picking up that last "referenced" `$item` when you run it on the `$arr` – Darren Jul 09 '15 at 03:59
  • 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())? – Tran Huynh Jul 12 '15 at 18:21
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

Raz
  • 81
  • 4
-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

Sagar
  • 642
  • 3
  • 14
  • 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? :) – Tran Huynh Jul 08 '15 at 06:31