4

I was going to explain to our intern the difference between "pass by reference" and "pass by value" in PHP, and did this simple script:

$a=5; 
$b=&$a; 
$a=8; 
echo $b;
// prints  8
$a=5; 
$b=$a;  //no &
$a=8; 
echo $b;
// prints 5

However, running this in php-cli using php -qa yields:

php >     $a=5; 
php >     $b=&$a; 
php >     $a=8; 
php >     echo $b;
8
php >     // prints  8
php >     $a=5; 
php >     $b=$a;  //no &
php >     $a=8; 
php >     echo $b;
8
php >     // prints 5

Should not the $b=$a; unlink $a and $b?

... so I got curius, and tried:

php > $b=3;
php > echo $a;
3

So, how did I get this wrong? What's going on here? It seems the reference-setting is somehow sticking, even though it should be cleared at the line $b=$a? I also tried:

php >    $e=5; $f=$e; $e=6; echo $f; 
5

...Which works as expected.

$a and $b seems linked permanently? Am I missing some big point here? How do I "unlink" the $a and $b variable?

3
  • Have you tried unset($b) before the second part? Commented Aug 22, 2011 at 11:43
  • Don't re-use variable names in the same scope if you don't explicitly mean the same. Commented Aug 22, 2011 at 11:49
  • 3
    +1 because this questions shows how trying to explain something to newbies can help you understand it better. Commented Aug 22, 2011 at 11:52

6 Answers 6

6

Why should the reference be cleared if you assign a value to a variable? It works like this (with semi-simplified comments):

$a = 5;    // creates a "slot", puts 5 in it, makes $a point to it
$b =& $a;  // makes $b point to the same "slot" $a points to
$c = 6;    // creates a "slot", puts 6 in it, makes $c point to it
$a = $c;   // puts the value of the slot $c points to into the slot $a points to
echo $b;   // outputs the value of the slot $b points to (6)

It's assigning a value to a variable. Whether the value is literal (5) or the value held by another variable doesn't matter. The reference stays until you unset($b).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the many comments here:) and your explanation is very good deceze. I assumed (obviously incorrect) that $b=$a would make a new slot for $b with a copy of the value of $a, but I see now that would probably be terribly unefficient. Thanks anyway! Jonas
@user Efficiency is not really the issue, rather that's how it's logically supposed to work.
1

Well, yeah, because you created $b as a reference to $a. So, what you're doing on the line:

$b = $a

is just assigning 5 to $a, because $b still references $a.

If you'd want to 'unreference' it, you'd have to unset and recreate the variable.

Comments

0

The first time your code makes any use of $b, it creates the variable $b and links it to the location of $a. Subsequently you're writing values into the shared location. You can't undo what location a variable references.

Comments

0

Following up on my comment... I ran your script - and it did output '8' in both cases. I added unset($b) after the first echo and ran again - now the output was 85, as expected.

Comments

0

The problem is that when you do $b = $a, as $b is a reference to $a you're doing $a = $a in fact. As told by other people, you'd have to unset($b).

Comments

0

Maybe using more speaking variable names make this more clear to you:

$value = 5; 
$alias = &$value; 
$value = 8;
echo $alias;   # 8
$value = 5; 
$alias = $value; # no &
$value = 8;
echo $alias;   # 8 (OP expected 5)

This is easier to read, right?

Take a note especially on this line:

$alias = $value; # no &

What does happen here?

As $alias is an alias to $value, you're basically writing:

$value = $value;

Which is 5 at this stage.

Then you set $value to 8.

The $alias is still referring to $value.

If you want to stop $alias being an alias to $value, you can turn it into an alias to something else:

$alias = &$other;

Or just unset the reference:

unset($alias);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.