【问题标题】:Return by reference in PHP在 PHP 中通过引用返回
【发布时间】:2023-03-19 14:13:01
【问题描述】:

我尝试了谷歌搜索,尝试了 PHP 文档,搜索了 Stack Overflow 的答案,但找不到任何令人满意的东西。我正在读一本书,其中作者使用了Return by Reference,但从未解释过它是什么。作者使用的代码是

function &getSchool() {
    return $this->school;
}

有人可以用简单的话解释一下这个概念吗?

【问题讨论】:

  • PHP docs 是对此的最终答案——请务必浏览所有“参考说明”部分。
  • Cmon Jon,我已经说过我已经阅读了文档,并且承认我从那里并没有很好地理解它。这就是我在这里问的原因,如果您有任何版本要解释,我将不胜感激:)
  • Jon 提供的链接通过示例很好地解释了这一点。
  • @IbrahimAzharArmar:通过示例代码和解释添加了完整答案,希望对您有所帮助:)

标签: php reference return


【解决方案1】:

假设你有这个类:

class Fruit {
    private $color = "red";

    public function getColor() {
        return $this->color;
    }

    public function &getColorByRef() {
        return $this->color;
    }
} 

该类有一个私有属性和两个允许您访问它的方法。一个按值返回(默认行为),另一个按引用返回。两者的区别在于:

  • 使用第一种方法时,您可以对返回的值进行更改,这些更改不会反映在 Fruit 的私​​有属性中,因为您实际上是在修改属性值的副本。
  • 当使用第二种方法时,您实际上得到的是 Fruit::$color 的别名——一个不同的名称,您通过它来引用 相同的变量。因此,如果您对它进行任何操作(包括修改其内容),您实际上是在直接对属性的值执行相同的操作。

这里有一些代码来测试它:

echo "\nTEST RUN 1:\n\n";
$fruit = new Fruit;
$color = $fruit->getColor();
echo "Fruit's color is $color\n"; 
$color = "green"; // does nothing, but bear with me
$color = $fruit->getColor();
echo "Fruit's color is $color\n"; 

echo "\nTEST RUN 2:\n\n";
$fruit = new Fruit;
$color = &$fruit->getColorByRef(); // also need to put & here
echo "Fruit's color is $color\n"; 
$color = "green"; // now this changes the actual property of $fruit
$color = $fruit->getColor();
echo "Fruit's color is $color\n"; 

See it in action.

警告:我觉得有必要提一下,虽然它们确实有合法用途,但它们是那些应该很少使用的功能之一,只有在你仔细考虑过任何替代品的情况下才能使用首先。经验不足的程序员倾向于过度使用引用,因为他们认为可以帮助他们解决特定问题,同时又不会看到使用引用的缺点(作为一项高级功能,其细微差别远非显而易见)。

【讨论】:

  • 另一方面,所有这些都在文档中有效,但是当接收端没有提到&符号时会发生什么,以及如何在类中禁用按值复制?例如。对于单例类。因为如果您必须指望调用者表现良好,那么知道您想要返回一个值没有多大意义,是吗?
【解决方案2】:

简单规则:如果您在 PHP 中的函数名称前放置 &,您可以在调用函数(即它的返回值)时使用 &,就好像它是一个变量而不是一个函数。

就是这样。


更容易将其视为“PHP 允许您引用返回值”,而不是 PHP 通过引用返回。如上所述,您只需放置一个 & 来告诉 PHP 您想要这个,如果您不放置它并尝试对 $var =& somefunction() 执行此操作,您将收到错误“仅应通过引用分配变量”。

为了消除对 Jon 的回答的一些困惑。实际上没有必要有两个单独的函数,一个按引用返回,一个按值返回;在某些项目约定之外。 &允许它通过引用返回,它不强制它通过引用返回。

例如。用于引用和非引用分配的相同函数

\header('content-type: text/plain');

class Demo
{
    protected $example = 'original value';

    function & example()
    {
        return $this->example;
    }
}

$demo = new Demo;

#1 - pass by value

$var1 = $demo->example();
$var1 = 'var1 value';

echo '$demo->example() => '.$demo->example().PHP_EOL;
echo PHP_EOL;

#2 - pass by reference

$var2 =& $demo->example();
$var2 = 'var2 value';

echo '$demo->example() => '.$demo->example().PHP_EOL;
echo '$var1 => '.$var1.PHP_EOL;
echo '$var2 => '.$var2.PHP_EOL;
echo PHP_EOL;

#3 - altering other references

$var3 =& $demo->example();
$var3 = 'var3 value';

echo '$demo->example() => '.$demo->example().PHP_EOL;
echo '$var1 => '.$var1.PHP_EOL;
echo '$var2 => '.$var2.PHP_EOL;
echo '$var3 => '.$var3.PHP_EOL;
echo PHP_EOL;

exit;

输出

$demo->example() => original value

$demo->example() => var2 value
$var1 => var1 value
$var2 => var2 value

$demo->example() => var3 value
$var1 => var1 value
$var2 => var3 value
$var3 => var3 value

参考很好,但是如果您不熟悉它们,请遵循以下规则:

  • 仅在处理大型数组或类似的非对象数据结构时才考虑使用引用
  • 永远不要引用对象(如果可以避免的话)
  • 仅当值保留在对象的静态属性或属性中时才允许函数通过引用传递(即,它不是函数内部的临时变量)

异常显然是非常实用的用途(即,当您真正想要共享一个值以简化操作它的代码时)。

再次,永远不要引用对象(这毫无意义!)

【讨论】:

    【解决方案3】:

    您发布的示例可能来自 PHP4 或更早版本。不再需要通过引用返回对象,因为在 PHP5+ 中它们几乎总是以这种方式自动完成。

    当你想使用一个函数来返回引用时很有用 找到一个引用应该绑定到哪个变量。不使用 通过引用返回以提高性能。发动机将 自动对其进行优化。仅在以下情况下返回引用 您有正当的技术理由这样做。

    return references in PHP docs

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-11
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    相关资源
    最近更新 更多