按引用传递,$a = &$b,$a=$n和$b=$n是一样的吗?

6
我想理解按引用传递。这可能是个不太恰当的比喻,但它像牛顿第三定律(作用和反作用)吗?
例如,对于以下代码:
$a = 4;
$b = 2;
$n = 42;
$a = &$b;

$a=$n$b=$n 是一样的吗?$a$b 的值不是存储在同一个地址里吗?


请使用http://php.net/manual/en/language.references.pass.php了解相关内容。 - عثمان غني
显式地通过引用传递值已被弃用,并且在当前的PHP版本中无法执行。只有方法可以定义参数是否必须通过引用接收。 - Maks3w
@Maks3w 不,它并没有被弃用。只有在与 new 运算符一起使用时才被弃用。请参阅手册。自 PHP 5 开始,new 自动返回一个引用,因此在这种情况下使用 =& 已经被弃用,并且在 PHP 5.3 及更高版本中会产生 E_DEPRECATED 消息,在早期版本中会产生 E_STRICT 消息。 - Shiplu Mokaddim
4个回答

10
如果你按照常规方式分配这些变量:
$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

是的,在将$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=$n 的意思是将 $n 的值存储到 $a 引用的位置。这个位置和 $b 是相同的。" 然后说 "分配新值,而不是引用 $a 和 $b 中的任何一个。" - Maks3w
"这是与 $b 相同的位置。$a 在新的内存空间中有一个新的值。" - Maks3w
@Maks3w,所以赋新值意味着在内存中新分配空间?在我的例子中哪里没有展示它? - Shiplu Mokaddim

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

-1

$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

1
-1 对象在这里的上下文中不存在。其他部分根本没有回答问题。 - Shiplu Mokaddim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接