【问题标题】:why is the code behaving this way WRT reference return?为什么代码会以这种方式运行 WRT 引用返回?
【发布时间】:2012-01-27 02:06:38
【问题描述】:

这是我的设置:
display_startup_errors = on
display_errors = 开启
error_reporting = E_ALL | E_STRICT

$b;
function func ($name) {
  global $b;
  $b = 10;
  return $b;
  }
$a =& func("myname");
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/> ";

以上代码输出如下提示:

严格的标准:只能通过引用在 /path/to/file/file.php 中的“某些行号”行中分配变量
$a= 11 $b= 10
a: (refcount=1, is_ref=0)=11

为什么上面的代码会显示通知?为什么会发生 C.O.W(写入时复制)?

$b;
function &func ($name) {//change here: to return a reference.
  global $b;
  $b = 10;
  return $b;
  }
$a =& func("myname");
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/> ";

上面的代码会输出:

$a= 11 $b= 11
a: (refcount=1, is_ref=1)=11

为什么这里没有发布严格的标准通知?这里的参考有效。

$b;
function &func ($name) {
  global $b;
  $b = 10;
  return $b;
  }
$a = func("myname"); //change here: removed &
++$a ;
echo '<br/>$a= '.$a.' $b= ' .$b."<br/>";
xdebug_debug_zval('a'); echo "<br/> ";

上面的代码会输出:

$a= 11 $b= 10
a: (refcount=1, is_ref=0)=11

为什么要在这里举行 C.O.W?

有关 xdebug_debug_zval 的信息,请访问here

【问题讨论】:

    标签: php copy-on-write reference


    【解决方案1】:

    &amp; 在 PHP 中作为参考的运算符在最近的版本中被删除。特别是来自 PHP5。 现在所有的引用类型数据(类等)都通过引用自动传递。

    阅读Returning ReferencesPassing by Reference

    【讨论】:

    • 不,除非您明确定义它,否则它不会通过引用传递。在您提供的链接上,只有您可以看到,他们正在使用 &amp; 运算符,因此它通过引用返回。
    • @Pradeep 我发布了两个链接。你看到第一个了吗?
    • @Shilpu 是的,在第一个链接中,您可以看到他们使用了 &amp; 运算符。他们提到 PHP 尝试优化传递返回值,但这不会改变行为。
    【解决方案2】:

    您的第二个 sn-p 工作正常。

    在 PHP 中,如果你想通过引用返回,你必须在分配时在定义中编写 use &amp; 运算符。见PHP reference Doc。因此,2nd 具有正确的语法,并且它可以在没有任何警告的情况下工作。

    首先 sn-p 发出警告,因为您尚未定义此函数将返回引用,并且您仍在通过引用分配其返回值。所以,它不会起作用。 (请参阅a 的值增加到 11,但 b 仅为 10。)

    在第三个 sn-p 中,您没有分配参考,因此它没有给出任何警告。 (但因为这个引用不起作用。(查看ab 值的区别)

    【讨论】:

      【解决方案3】:

      我怎么会错过这个:这完全使我的问题无声! 来自Returning References PHP 手册

      注意:如果您尝试使用以下语法从函数返回引用:return ($this->value);这将不起作用,因为您试图通过引用返回表达式的结果,而不是变量。您只能通过函数引用返回变量 - 仅此而已。由于 PHP 4 分支中的 PHP 4.4.0 和 PHP 5 分支中的 PHP 5.1.0,如果代码尝试返回动态表达式或 new 运算符的结果,则会发出 E_NOTICE 错误。

      To use the returned reference, you must use reference assigment:

      <?php
      function &collector() {
        static $collection = array();
        return $collection;
      }
      $collection = &collector();
      $collection[] = 'foo';
      ?>
      

      【讨论】:

        猜你喜欢
        • 2021-07-19
        • 2014-08-28
        • 2021-11-11
        • 2021-12-20
        • 1970-01-01
        • 1970-01-01
        • 2016-04-21
        • 1970-01-01
        • 2011-11-04
        相关资源
        最近更新 更多