There is the following PHP code:

<?php function func(&$r) { $r++; } $r = 1; func(func($r)); echo $r; ?> 

and he gives out 2.

And this code:

 <?php function func(&$r) { $r++; } $r = 1; func($r); echo $r; ?> 

Also issues 2.

Why both give out the same value?

And how to understand the string func(func($r)) ? Can a function pass itself as an argument?

  • No return, what are you hoping for? - Makarenko_I_V

4 answers 4

The function code takes an argument by reference, that is, it can change its value in the calling code.

Why both give out the same value?

With the second case, everything should be easy. Set the initial value of the variable. Called a function that increased its value. As a result, we have 2 .

In the first case, there is a nested function call. Here, the call func($r) in the same way increases the value by 1. Then the result of the function execution (which is not actually defined, since the function does not have a return ) is passed as an argument to the same function again. But since the call argument is no longer $r (but the undefined result of the first call), then, of course, the value of this variable will not change.

And how to understand the string func (func ($ r))

understand exactly as written, call the function func and its result once again to the function func . That is, formally, if this is easier for you to understand, it will be equivalent to writing

 $result = func($r); func($result); 

Can a function pass itself as an argument?

again, the result of the execution is transmitted, and not itself. However, the approach with the transfer of references to the function is very common. This is called a callback method (or callback function). The simplest example of passing a function as a parameter is sorting usort() . Example:

 $data = [0,1,2,3, 1,2]; usort($data, function($a,$b){ return $a - $b;}) ; //либо для PHP 7 usort($data, function($a, $b){ return $a <=> $b;}); 

As you can see here, the function reference is passed as a parameter. Moreover, this function is anonymous, i.e. It has no name and is defined right at the place of transmission

    Using & in the function declaration says that the variable passed into it will be changed by the function. Thus func($r); adds 1 to the variable.

    func(func($r)); can be broken down into 2 stages. func($r) and func(/*результат выполнения функции*/)

    func($r) adds 1 to $r and returns null (functions without return return null ). Thus, the second function goes not to $r , but to null func(/*результат выполнения функции == null*/) , therefore it does not affect $r in any way.

    To use such constructs, you need to use return and the appropriate variable assignment style:

     <?php function func($r) { return $r+1; } $r = 1; $r = func(func($r)); echo $r; ?> 
       func(func($r)); 

      In this case, you should receive a warning:

      PHP Notice: Only variables should not be passed by reference in ...

      The first (nested) call to func() correct, because it is passed a reference to the variable $r . In the second call, there is no reference: the role of the argument is the value that the first call to func() returns.

      Conclusions: read not only textbooks, but also interpreter messages.

        In addition to the above:
        If you want to use such a chained transfer by reference, you also need to return the value by reference:

          function &func(&$r) { $r++; return $r; } $r = 1; func(func($r)); echo $r; // 3 

        Notice the ampersand in front of the function name.
        He says that the result does not need to be copied to a temporary value; you just need to return a reference to the same variable.

        So exactly what you expect happens. The function changes the external variable and returns a reference to it, which can be passed to another (or the same) function that requires a reference to the input.