通过引用传递$ a =& $ b,$ a = $ n与$ b = $ n相同?

时间:2013-01-15 07:47:54

标签: php pass-by-reference

我试图理解通过引用传递。这可能是一个很糟糕的比喻,但它是否像牛顿第三定律(动作 - 反应对)?

例如,对于以下代码

$a = 4;
$b = 2;
$n = 42;
$a = &$b;

$a=$n$b=$n相同? $a$b的值是否存储在同一地址?

4 个答案:

答案 0 :(得分:7)

如果您正常分配这些变量:

$a = 1;
$b = 2;
$c = 3;

然后协会将如下所示:

a --> 1
b --> 2
c --> 3

现在,如果您将$c变为$a的引用,就像这样:

$a = 1;
$b = 2;
$c = &$a;

然后协会将如下所示:

a --> 1 <--.
b --> 2    |
c --------/

换句话说,$a$c指向相同的值。因为它们都指向相同的值,所以我们可以更改任一变量,它们都会指向新值。

$a = 5;
echo "$a $c"; // Output: "5 5"
$c = 10;
echo "$a $c"; // Output: "10 10"

答案 1 :(得分:1)

,将$n分配给$a后, $b将指向$n

这是因为执行$a=&$b$a$b引用了相同的内存位置并成为引用变量(is_ref=1。并且该特定内存位置的引用计数(refcount)增加1现在无论分配给任何这些引用,都会指向相同的值。

执行$a=$n表示$n值将存储到$a引用的位置。这与$b的位置相同。

请参阅此处的示例。

$a$b$n指向不同的位置

php > $a = 4;
php > $b = 2;
php > xdebug_debug_zval('a'); // they are pointing different location
a: (refcount=1, is_ref=0)=int(4)

php > xdebug_debug_zval('b'); // they are pointing different location
b: (refcount=1, is_ref=0)=int(2)

php > $n = 42;
php > xdebug_debug_zval('n'); 
n: (refcount=1, is_ref=0)=int(42)

$ a和$b现在都成为参考

php > $a = &$b; 
php > xdebug_debug_zval('b');
b: (refcount=2, is_ref=1)=int(2)

php > xdebug_debug_zval('a'); // a too
a: (refcount=2, is_ref=1)=int(2)

指定新的,不引用任何$a$b

php > $a = $n;
php > xdebug_debug_zval('a'); // a holds $n's value '42' now
a: (refcount=2, is_ref=1)=int(42)


php > xdebug_debug_zval('b'); // same for b
b: (refcount=2, is_ref=1)=int(42)

答案 2 :(得分:0)

通常在创建变量$a$b时,每个变量都有一个唯一的内存地址,用于存储数据。

但是,如果你告诉口译员$a = &$b,这意味着$ a和$ b现在有相同的内存地址。如果你给$ a或$ b分配任何东西,它们都会回显相同的值,因为它们将数据存储在内存中的相同位置。

如果你想进行实验,我建议从命令行启动PHP交互式解释器:

php -a
php > $a = 1;
php > $b = 2;
php > echo $a . ' ' . $b;
1 2
php > $a = &$b;
php > echo $a . ' ' . $b;
2 2
php > $a = 1;
php > echo $a . ' ' . $b;
1 1
php > $b = 2;
php > echo $a . ' ' . $b;
2 2

答案 3 :(得分:-1)

$a = $b&amp; $b = $n具有相同的值但不同,因为该值是基本类型并且primitive types pass by value

测试代码是否使用引用的最快速方法是更改​​源var的值,并查看目标变量是否更改其值。

$n = 1;
$a = $n;
$b = $n;

echo $a; // 1
echo $b; // 1
echo $n; // 1

$n = 2;

echo $a; // 1
echo $b; // 1
echo $n; // 2

然而objects always are passed by reference

$n = new Object(1);
$a = $n;
$b = $n;

$n->newValue(5);

$a->printValue(); // 5
$b->printValue(); // 5

$a->newValue(7);

$b->printValue(); // 7