在 PHP 中按引用返回

2022-08-30 14:32:41

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

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

有人可以用简单的语言解释一下这个概念的例子。


答案 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"; 

查看实际效果

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


答案 2

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

就是这样。


更容易将其视为“PHP允许您引用返回值”,而不是通过引用返回的PHP。如上所述,你只需放置一个告诉PHP你想要这个,如果你不放置它并尝试这样做,你会得到错误“只有变量应该通过引用分配。&$var =& somefunction()

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

例如。用于引用和非引用赋值的相同函数

\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

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

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

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

同样,永远不要引用对象(这是毫无意义的!


推荐