2011-08-22 76 views
4

我要“按引用传递”给我们的实习生解释之间的差异,在PHP“按值传递”,并做了这个简单的脚本:PHP通过引用传递/值 - 问题

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

然而,使用PHP -qa产量在PHP-CLI运行以下命令:

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 

应该不是$b=$a;取消链接$ a和$ b?

...所以我就curius,并尝试:

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

那么,为什么我得到这个错了吗?这里发生了什么?看起来参考设置有点困难,即使它应该在行$b=$a清除?我也试过:

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

...其中按预期工作。

$a$b似乎永久链接?我在这里错过了一些重点吗?如何“取消链接”$a$b变量?

+0

你试过'未设置($ b)'在第二部分之前? –

+0

如果您没有明确表示相同的范围,请不要在相同范围内重用变量名称。 – hakre

+3

+1,因为这个问题显示了如何试图向新手解释一些东西可以帮助你更好地理解它。 – Arkh

回答

6

如果给变量赋值,为什么应该清除引用?它的工作原理是这样的(半简化的注释):

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

它分配一个变量。无论值为,文字5)还是其他变量所持有的值均无关紧要。该参考文件一直保留至unset($b)

+0

感谢这里的许多评论:)你的解释是非常好的欺骗。我认为(显然是不正确的)$ b = $ a会为$ b创建一个新的槽,并带有$ a的值副本,但我现在看到这可能会非常不够高效。 还是谢谢! Jonas – jonasfh

+0

@user效率并不是真正的问题,而是它在逻辑上应该如何工作。 – deceze

1

嗯,是的,因为你创建了$b作为参考$a。所以,你做一下就行了:

$b = $a 

只是分配5到$一个,因为$b仍然引用$a

如果您想'重新引用'它,您必须unset并重新创建该变量。

0

您的代码首次使用$ b时,会创建变量$ b并将其链接到$ a的位置。随后您将值写入共享位置。您无法撤消变量引用的位置。

+0

撤消:'unset()'。 – hakre

0

继续我的评论...我跑你的脚本 - 它确实在两种情况下输出'8'。我在第一个echo之后加了unset($b)并再次运行 - 现在的输出为85,如预期的那样。

0

问题是,当你做$b = $a,因为$ b是对$ a的引用,你实际上在做$a = $a。正如其他人告诉的那样,您必须登录unset($b)

0

可能使用更多的讲的变量名称使这更清楚你:

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

这是更容易阅读,对不对?

记事尤其是在这条线:

$alias = $value; # no & 

是什么发生在这里?

由于$alias是一个别名$value,你基本上可以写:

$value = $value; 

这是5在这个阶段。

然后,设置$value到8

$alias仍参照$value

如果你想停止$alias是一个别名$value,你可以把它变成一个别名别的东西:

$alias = &$other; 

或者正好被清除参考:

unset($alias);