0

Here is the simplified version of code that might be revealing a PHP bug

class AClass
{
    public static $prop = "Hi";
}
function assignRef (&$ref)
{
    $ref = &AClass::$prop;
    echo "inside assignRef: $ref\n";
}
$ref = "Hello";
assignRef($ref);
echo "outside: $ref\n";

This prints out

inside assignRef: Hi
outside: Hello

Shouldn't $ref had been assigned by reference to $prop static variable of the AClass class and become "Hi" not just inside assignRef function but also outside of it?

Desmond Hume
  • 8,037
  • 14
  • 65
  • 112
  • `$ref = "Hello"` will overwrite the variable with the string "Hello" if I am not mistaken – David Wilkins Apr 08 '14 at 13:58
  • 1
    isn't the & in the parameter declaration what you want? Why also the & in "$ref = &AClass::$prop;" – RobP Apr 08 '14 at 14:00
  • @DavidWilkins `$ref` is not assigned at the time when `$ref = "Hello"` takes place – Desmond Hume Apr 08 '14 at 14:01
  • @DesmondHume You are right, I read the lines out of order....Thank goodness my brain doesn't run programs – David Wilkins Apr 08 '14 at 14:03
  • 1
    Your problem is the spurious `&` in `$ref = &AClass::$prop;` Change this to `$ref = AClass::$prop;` and it will work as you expect – Mark Baker Apr 08 '14 at 14:04
  • @MarkBaker Then it won't be referencing `$prop` but I want `$ref` to be a reference to `$prop` if the function decides so – Desmond Hume Apr 08 '14 at 14:06
  • @bwoebi yes, quite possible – Desmond Hume Apr 08 '14 at 14:07
  • Hm what for you do `&AClass` I mean `&` for static method... Yes code is right (I think so) why this happens - good question. – user1954544 Apr 08 '14 at 14:07
  • @JasonFingar not really – Desmond Hume Apr 08 '14 at 14:08
  • PHP references are not C pointers. It seems like a pretty bad idea to me to want to return a reference by reference, it's simply not great (PHP) API design by any means and will produce weird side effects as you lose track of your references. – deceze Apr 08 '14 at 14:16
  • @deceze finally a voice of intelligence – Desmond Hume Apr 08 '14 at 14:18
  • Are you seriously asking the same question again even after you received the correct answer from @bwoebi ? – hndr Apr 08 '14 at 14:21
  • @that_guy I asked this simplified version before bwoebi answered with his hardly acceptable answer – Desmond Hume Apr 08 '14 at 14:22
  • @DesmondHume First, you know you can edit your questions. Second, I don't see how his answer is hardly acceptable, and the comments on the answer also mentioned how reference in PHP is not the same as C/C++ pointers. I feel like you created this questions just to be condescending. – hndr Apr 08 '14 at 14:29
  • 1
    @DesmondHume why is my answer _hardly acceptable_? It's just the way it is. Some limitations are there just by design. There are even things the C language doesn't allow (like http://stackoverflow.com/questions/19681025). – bwoebi Apr 08 '14 at 14:33

1 Answers1

0

The class in your example is irrelevant, simplified version that produces the same output:

function assignRef (&$ref)
{
    $prop = 'Hi';
    $ref = &$prop;
    echo "inside assignRef: $ref\n";
}
$ref = "Hello";
assignRef($ref);
echo "outside: $ref\n";

What is happening is that when assigning by reference inside the function ($ref = &$prop;) you are just changing what one variable is pointing to, not changing the value of what it was originally pointing to nor changing any other references to that original value.

You effectively have two variables called $ref in this example - one inside the function, and one outside the function. You are changing what the variable inside the function points to, leaving the other variable pointing to the original (unchanged) value.

Consider the following code:

$a = 'a';
$b = 'b';
$c = 'c';

$a = &$b;
$b = &$c;
echo "$a / $b / $c";

This results in output of b / c / c, rather than what you might expect c / c / c. This happens for the same reason - assignment by reference does not affect the value originally referenced nor change any other references, meaning any other variables pointing to the original value are unchanged.

If you want to change the value, rather than creating a new reference to another value, you must use normal assignment (=). Alternatively, you could change all references.

Mitch Satchwell
  • 4,770
  • 2
  • 24
  • 31
  • The 2 pieces of code are not related in my opinion, the results of the second code are totally normal and expected – Desmond Hume Apr 08 '14 at 14:30
  • 1
    How is it different? When passing by reference to a function you have two variables pointing to the same value, changing what one of these points to does not effect the original value. This is exactly the same as what I am doing in my abc example. – Mitch Satchwell Apr 08 '14 at 14:31