我想理解按引用传递。这可能是个不太恰当的比喻,但它像牛顿第三定律(作用和反作用)吗?
例如,对于以下代码:
例如,对于以下代码:
$a = 4;
$b = 2;
$n = 42;
$a = &$b;
$a=$n
和 $b=$n
是一样的吗?$a
和 $b
的值不是存储在同一个地址里吗?
$a = 4;
$b = 2;
$n = 42;
$a = &$b;
$a=$n
和 $b=$n
是一样的吗?$a
和 $b
的值不是存储在同一个地址里吗?
$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"
是的,在将$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)
$a
和$b
时,它们各自拥有一个唯一的内存地址,用于存储它们的数据。$a = &$b
,那么$a和$b现在拥有相同的内存地址。如果您将任何值分配给$a或$b,它们都将输出相同的值,因为它们在内存中的同一个位置存储数据。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
$a = $b
& $b = $n
具有相同的值,但是它们是不同的,因为该值是原始类型,而原始类型按值传递
。
测试代码是否使用引用最快的方法是更改源变量的值并查看目标变量是否更改其值。
$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
然而,对象总是按引用传递
$n = new Object(1);
$a = $n;
$b = $n;
$n->newValue(5);
$a->printValue(); // 5
$b->printValue(); // 5
$a->newValue(7);
$b->printValue(); // 7
new
运算符一起使用时才被弃用。请参阅手册。自 PHP 5 开始,new
自动返回一个引用,因此在这种情况下使用=&
已经被弃用,并且在 PHP 5.3 及更高版本中会产生 E_DEPRECATED 消息,在早期版本中会产生 E_STRICT 消息。 - Shiplu Mokaddim