在PHP中,当$ foo = new Foo()时,从技术上讲,$ foo是一个对象,还是$ foo的引用?

时间:2010-10-18 10:34:50

标签: php pass-by-reference pass-by-value object-reference php-internals

更新:

  

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

它说:

  

PHP5 OOP的关键点之一   经常提到的是“对象   默认情况下通过引用传递“。   这不完全正确。

为什么?以下是我不知道的完全正确的原因:

我认为松散地说,foo可以说是一个对象,或者是Foo类的一个实例。

但从技术上讲,foo只是一个引用,在Java和Ruby中完全相同,其中变量foo始终只是对象的引用。

这就是为什么在PHP中,

function add($obj) {
  $obj->a++;
}

我们没有说“通过引用传递”,但从技术上讲,我们传递的是一个值,这是一个参考。所以,它是“传递 引用”,而不是“通过 引用传递 ”。

但是,如果我们在PHP中说foo是一个对象,那么我猜“通过引用传递”是有道理的。这是真的吗? foo被认为是对象的引用,而不是对象,所以我们只是“通过价值传递”?

3 个答案:

答案 0 :(得分:1)

$foo不是对象,它是一个引用。假设$foo是一个对象是错误,$foo是指向对象的引用。

引用按值传递,就像PHP中的任何其他参数一样(Java和Ruby也是如此),因此您不能直接指定引用来修改引用,但是您可以根据需要在它指向的对象上工作。

为了简化抽象,程序员有时会说“$foo是一个对象”,这是错误的,但它比说“$foo是一个指向对象的引用更容易” ”。在许多情况下,除了在某些边缘情况下,差异实际上并不重要。

答案 1 :(得分:0)

默认情况下,所有对象都在PHP 5+中通过引用传递,在PHP 5之前通过引用传递,您使用了“&”运营商

这意味着如果将对象传递给方法,则复制引用,并且方法内的另一个变量将包含引用的副本。

所以你不是默认情况下通过引用传递引用:),所以你不能分配包含引用副本的变量一个新值并影响原始引用。

答案 2 :(得分:0)

PHP对象变量实际上并不包含对象(就像在许多其他语言中一样) - 它包含对象的“句柄” - 即一些允许识别对象,找到并操纵它的值。这个变量和其他变量一样传递 - 它可以通过-val,by-ref等传递。但是,如果你将这个值复制到另一个变量,那么事情发生的变化与整数或字符串的变化相同和不同。 / p>

整数/字符串:复制值,因此当它被修改时,另一个保持不变。

对象:复制值,但值是句柄。因此,如果此句柄用于访问实际对象(这几乎是使用此句柄的唯一方法)并且此访问权限修改它,那么另一个变量 - 独立但包含相同的句柄 - 将反映更改。

所以它实际上是非常一致的,只是有点不像你期望的那样“按价值”和“通过引用”天真地对待 - 因为传递的内容对于标量和对象变量实际上是不同的。对象变量包括间接级别。

这是,顺便说一下,为什么通过引用传递对象变量几乎没有意义 - 除非你想在函数中用另一个对象替换一个对象。