PHP ignores passing by reference if var is assigned by a function call

I have two functions

function c( &$x ) { $x = 25; echo 'c is called, x = ' . $x . PHP_EOL; } function b() { echo 'b is called'. PHP_EOL; return 5; } 

Then I will write the following code, which, as I expect, should put the result of b () in $ o, and then pass $ o with a reference to c (), where it is set to the new value. It works fine:

 $o=b(); c( $o ); echo 'o is '.$o; 

the output will be as expected:

 b is called c is called, x = 25 o is 25 

But if I try to assign the value $ o in the function call as follows:

 c( $o = b() ); echo 'o is '.$o; 

I get a strange conclusion

 b is called c is called, x = 25 o is 5 

the order of the function calls remains the same, but why does $ o not change, despite the fact that it was passed by reference? Does PHP force an argument by value if it is assigned in a function call? If so, which version did it work with? According to this comment: http://www.php.net/manual/en/functions.arguments.php#71198 in 2006, it worked differently. My version is 5.3.6

+4
source share
1 answer

This is a limitation of the Zend engine that I encountered earlier, especially when using socket_select() / stream_select() , for which both arguments to the “resource array” are passed by reference. It would be nice to assign the values ​​of the variables that will be passed by reference in one line, but it is not possible (at present) to do this.

I already mentioned this before ( although right now I cannot find where (here here ), and perhaps it was not authoritative) that any expression in PHP is evaluated on the right side of the expression. By this I mean:

 $a = 1; $b = 2; echo $a = $b; 

This will be echo 2 , because the expression that was passed by the echo operator evaluates to the right side of the expression $b , which is 2 .

When passing the result of a function expression, for example, c( $o = b() ); where you pass the result $o = b(); to the c() function, I understand (although I could be wrong) that the result of the expression is passed to the function and the function is executed before zval is created and assigned to store $o , a behavior that was designed to reduce memory consumption and speed up internal processing, when functions are nested this way. This means that you did not actually pass the variable by reference, you just passed the value obtained from b() , the right side of the expression, which cannot be changed by reference, because it does not have a container variable.

In fact, if you enable E_STRICT messages, you will see the following error:

Strict standards: only variables should be passed by reference in ...

... therefore this behavior is truly "by design".

+3
source

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


All Articles