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);
精彩评论