Problem with passing variable reference

<?php function requestSecond($param) { $param['conf']++; } function requestFirst($params) { $params['conf']++; requestSecond($params); } $conf = 1; requestFirst(array( 'conf' => &$conf, )); echo $conf; 

Result: 3

Question:

I know that &$conf means passing the link to $conf , so I understand after requestFirst($params) , $conf=2 , but I don’t understand why after requestSecond($param) , $conf=3 , requestSecond($param); does this also pass the value $conf not the value?

+4
source share
5 answers

$conf in requestFirst is a link, it will still be a link when you pass it to a new function. This will be the link even if you assign it to a local variable inside requestFirst.

eg:

 function requestFirst($params) { $params['conf']++; $stillReference = $params; // $stillReference will also hold reference to $conf $local = array( 'conf' => $params['conf']); // This will be local and the output will be 2 requestSecond($stillReference); //outputs 3 } 

In the above example, there is no difference between $params and $stillReference , and both of them use the same internal container of variables. The only way to separate the two is to invalidate one of the variables using unset() .

0
source

Yes, $conf in requestFirst is a link, so if you use this variable on new calls, it is still a link.

If you use var_dump($params) , you'll see that conf is a reference array(1) {["conf"] => &int(2)}

0
source

The array contains a link to $ conf, so this is what you are going through.

i.e. you have an array with one element of 'conf', which is a reference to $ conf, so when you call $param['conf']++ , you call ++ in the reference $ conf, not the array that was passed in value. Both of your functions take parameters by btw value.

I think your confusion comes in that &$conf means a $conf link, but you assign it to an array element without passing it as a requestFirst($params) link if you want requestFirst to accept a link, not a value which you would use instead of requestFirst(&$foo) .

0
source

requestFirst passes a light copy of the argument array to requestSecond as you expect. But since the original argument contains a link to $conf , the copy also contains a link. Therefore, when you modify this particular element, the change is visible through all other references to the $conf variable:

 function requestSecond($param) { $param['conf']++; // change to the int counter happens here } function requestFirst($params) { $params['conf']++; requestSecond($params); echo $params['conf']; // change is visible here } $conf = 1; requestFirst(array( 'conf' => &$conf, )); echo $conf; // change also visible here 

However, $param itself is still a copy of $params , and any changes made to it will not be displayed outside the requestSecond :

 function requestSecond($param) { $param['conf']++; $param['foo'] = 'bar'; } function requestFirst($params) { $params['conf']++; requestSecond($params); echo (int)isset($params['foo']); // "0" -- change not visible } 

You can even remove the link from the array after it is expanded; the change in the reference counter will remain, but the change in the array will not:

 function requestSecond($param) { $param['conf']++; // remove the reference from the array -- this will only affect // the local copy $param and nothing else unset($param['conf']); } function requestFirst($params) { $params['conf']++; requestSecond($params); echo $params['conf']; // 3 } 
0
source

When you execute requestSecond($params); , $params is the argument you pass requestFirst . You are passing a link to int, so your second function will also get that link. This is why the variable is updated twice.

0
source

Source: https://habr.com/ru/post/1497392/


All Articles