Search code examples
phpparameter-passingpass-by-referencepass-by-value

PHP how come one element of the array is by reference and the other by value when passing a two element array as a by value parameter?


Can someone explain this strange behaviour I am witnessing in PHP 8.1.6?

I guess the behaviour is according to standards, I just don't understand it. The function call has a parameter by value, yet the array is changed after the call, all because of the reference to the first element.

$arr = [3, 4];
$ref = &$arr[0] ;             // this statement causes the weird behaviour. Without it all is ok

print_r($arr);                // as expected
print_r(doSomethingTo($arr)); // as expected
print_r($arr);                // WHAT JUST HAPPENED?

function doSomethingTo($arr) {
    // $arr BY VALUE
    foreach($arr as $k => $v)
        $arr[$k]=$v+1 ;
    return $arr ;
}

result:

Array
(
    [0] => 3
    [1] => 4
)
Array
(
    [0] => 4
    [1] => 5
)
Array
(
    [0] => 4
    [1] => 4
)

Why? Why does the reference to the first array element change the behaviour of the by value parameter passing? The first element was now passed by reference to the function, and the second by value! ???

Thank you for an explanation!


Solution

  • A little complex formulated answer I found at https://www.php.net/manual/en/language.references.whatdo.php

    I will translate the answer to this particular situation.

    The thing many people may not realise, is, is that $a =& $b does not mean that $a references now to $b, but $a and $b BOTH become references to the same value that was originally contained in $b.

    So when evaluating $ref = &$arr[0] ; the $arr[0] element and the $ref become both references to the 3 value.

    Now when an array is passed as a parameter by value, the array is always duplicated. Same happens here.

    Which means the $arr[0] reference is duplicated too, i.e. in the duplicate array another reference is created to the same 3 value. So we have $ref, the original $arr[0] and the $arr[0] within the function all being references to the 3 value.

    When either of these three references gets an assignment, of course the value changes.

    Thank you @Sammitch for setting me on the right track!!!