【问题标题】:Passing by reference, $a = &$b, is $a=$n the same as $b=$n?通过引用传递,$a = &$b,$a=$n 和 $b=$n 一样吗?
【发布时间】:2012-12-29 06:50:04
【问题描述】:

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

比如下面的代码

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

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

【问题讨论】:

  • 通过引用显式传递值已被弃用,并且不能与实际的 PHP 版本一起使用。只有方法可以定义参数是否必须通过引用接收
  • @Maks3w 不,它没有被弃用。仅将其与 new 运算符一起使用已被弃用。请参阅manualSince PHP 5, new returns a reference automatically, so using =& in this context is deprecated and produces an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions

标签: php pass-by-reference


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    这是因为在执行$a=&amp;$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 中的任何一个的引用”
    • "这和 $b 是同一个位置"。 $a 在新的内存空间中有一个新的值
    • @Maks3w 所以分配新值意味着内存中的新空间?在我的示例中,我没有在哪里展示它?
    【解决方案3】:

    通常当您创建变量$a$b 时,每个变量都有一个唯一的内存地址来存储它们的数据。

    但是,如果您告诉解释器 $a = &amp;$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
    

    【讨论】:

      【解决方案4】:

      $a = $b & $b = $n 具有相同的值但不同,因为该值是原始类型和primitive types pass by value

      测试代码是否使用引用的最快速方法是更改​​源 var 的值并查看目标 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
      

      【讨论】:

      • -1 对象不在此处的上下文中。其他部分根本不回答问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 2017-04-06
      • 2016-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多