skip to Main Content

Why is the variable passed by reference not changed when the assignment is also made with a reference?

function foo(&$x) {
    $y = 1;
    $x = &$y;
}
$bar = 0;
foo($bar);
echo $bar; //why is this not 1?

This behavior seems to be identical in all PHP versions. Therefore I assume that the behavior is by design.

Is it documented somewhere that the reference is lost in such cases?

2

Answers


  1. References in PHP are a means to access the same variable content by different names. They are not like C pointers; for instance, you cannot perform pointer arithmetic using them, they are not actual memory addresses, and so on. [..] Instead, they are symbol table aliases. Note that in PHP, variable name and variable content are different, so the same content can have different names. The closest analogy is with Unix filenames and files – variable names are directory entries, while variable content is the file itself. References can be likened to hardlinking in Unix filesystem.

    What References Are

    <?php
    $a =& $b;
    ?>
    

    it means that $a and $b point to the same content.

    Note:
    $a and $b are completely equal here. $a is not pointing to $b or vice versa. $a and $b are pointing to the same place.

    What References Do

    So, $x = &$y; makes $x an alias of the value that $y is pointing to. If $x was an alias to some value before, that’s broken now, because it can only point to one value at a time.

    However, it feels wrong that you can destroy the passed by reference relationship.

    Well, that’s entirely up to you. If you understand how references work, then you are entirely in control of writing code that makes them work as you want them to.

    Login or Signup to reply.
  2. A variable is a name assigned to a value. You pass or use a variable by retrieving its value and work with this or by its name for later refering to it. Passing by reference has the problem that other processes may change the variable’s value while you are working with it. If you are passing by value, you give a new name to the value and have good chances that no other process will know this name and do unwanted things with the associated value.

    What is not possible is to make e.g. "x" first a reference to "bar" and then "x" a reference to "y" and then expect the name "bar" to be a new name for the value of "y". In other word you first said "with x I mean bar", then "with x I mean y", and then "give me the value assigned to bar". Where should be a change of the value assigned to "bar"? It’s nothing else than

    $bar = 0;
    $x = &$bar;
    $y = 1;
    $x = &$y;
    echo $bar; // 0
    

    What you expect from your function would require to explicitly "re-establish" the association between "x" and "bar" by assigning "bar" to "x":

    $bar = 0;
    $x = &$bar;
    $y = 1;
    $x = &$y;
    $bar = &$x;
    echo $bar; // 1
    

    Consider that your function foo(&$x) effectively is "function foo($x = &$bar)" (of course formally not possible to state). This makes clear that you have two competing $x = &, the winning last one fully overwriting the losing first one.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search