为什么我必须在函数调用中使用引用运算符(&)?

建立

我借用了一个我经常用于定制项目的开源CMS的功能。

它的目的对于这个问题并不重要,但如果你想知道它是一个简单的静态缓存,旨在减少数据库查询。 我可以在一个页面加载中调用getObject 10次,而不必担心会触发数据库10次。

该函数的简化版本如下所示:

function &staticStorage($name, $default_value = NULL)
{
  static $data = array();
  if (isset($data[$name])
  {
    return $data[$name];
  }
  $data[$name] = $default_value;
  return $data[$name];
}

这个函数可以这样调用:

function getObject($object_id)
{
  $object = &staticStorage('object_' . $object_id);
  if ($object)
  {
    return $object;
  }

  // This query isn't accurate but that's ok it's not important to the question.
  $object = databaseQuery('SELECT * FROM Objects WHERE id = @object_id', 
                          array('@object_id => $object_id'));
  return $object;
}

这个想法是,一旦我调用static_storage ,返回的值将更新静态存储,因为它被更改。

问题

我的兴趣在行$object = &staticStorage('object_' . $object_id); 注意函数前面的&staticStorage函数已经返回一个引用,所以我最初没有在函数调用之前包含引用操作符。 但是,如果没有函数调用之前的引用,它将无法正常工作。

我对指针的理解是,如果我返回一个指针,php会自动将该变量转换为一个指针$a = &$b将导致$a指向$b的值。

这个问题

为什么? 如果函数返回一个引用,为什么我必须在函数调用之前使用引用运算符?


来自PHP文档

Note: Unlike parameter passing, here you have to use & in both places - to indicate that you want to return by reference, not a copy, and to indicate that reference binding, rather than usual assignment, should be done for $myValue.

http://php.net/manual/en/language.references.return.php

基本上,它帮助php解释器。 函数定义中的第一个用途是返回引用,第二个用于通过引用而不是值绑定到赋值。

通过在函数声明中放入& ,函数将返回返回值的内存地址。 分配,得到这个内存地址时,将其解释值作为一个int,除非明确告知,否则,这就是为什么第二&需要使用赋值运算符。

编辑:正如@ringø下面指出的那样,它不返回内存地址,而是一个将被视为副本的对象(技术上写时拷贝)。


PHP文档解释了如何使用以及为什么返回引用的函数。

在您的代码中, getObject()函数还需要一个& (以及调用),否则引用将丢失,并且数据可用时基于PHP写时复制(返回的数据和源数据点都是相同的实际数据,直到其中一个数据发生变化=>具有不同寿命的两个数据块)

这不起作用(语法错误)

$a = array(1, 2, 3);
return &$a;

这不按预期工作(没有参考返回)

$a = array(1, 2, 3);
$ref = &$a;
return $ref;

并且不需要像上面所说的那样将&添加到函数调用中,也不会返回任何参考。

关于为什么......这个问题似乎没有一致的答案。

  • 如果其中一个&缺少PHP将数据视为不是引用(比如返回一个数组),而没有任何警告
  • 这里有一些与函数返回引用有关的奇怪
  • PHP在这些年来发展起来,但仍然继承了一些最初的糟糕设计选择。 这似乎是其中之一(此语法是很容易出错的一个可以轻易错过一个& ...并提前没有警告......;还有为什么不直接返回像一个基准return &$var; PHP取得了一些进展,但依然存在,可怜的设计痕迹依然存在。

    您也可能对上面链接的文档的这一章感兴趣

    不要使用按引用返回来提高性能。 引擎会自动优化它。 只有当你有合理的技术理由才能返回参考。

    最后,最好不要在C和PHP引用中的指针之间进行等价(Perl在这方面比PHP更接近)。 PHP在实际指向数据和变量以及引用点之间增加了一层,而不是实际数据。 但是参考不是一个指针。 如果$a是一个数组而$b是对$a的引用,则使用$a$b来访问数组是等同的。 有没有解引用语法,一个*$b在C.例如像$b应该被视为一个别名$a 。 这也是一个函数只能返回一个变量引用的原因。

    链接地址: http://www.djcxy.com/p/89875.html

    上一篇: Why do I have to use the reference operator (&) in a function call?

    下一篇: Moq and SqlConnection?