开发者

PHP pass by reference/value - question

I was going to explain to our intern the differe开发者_开发问答nce 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?


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).


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.


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.


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.


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).


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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜