PHP5对象是否通过引用传递?
我似乎无法得到任何一致的信息。 不同的来源似乎说不同的东西,而古老的php.net本身( 似乎 )没有明确说明这一点 – 但我必须承认,我只是看了一眼。
在我传递“重”对象的情况下,我需要通过引用传递,但是我不想继续input:
function foo(TypeName& $obj)
如果我可以简单地逃脱
function foo(TypeName $obj)
那标准说什么?
对象通过引用传递(并分配)。 不需要使用操作员的地址。
当然,我input的内容太简单了,但是会适合你的目的。 该文件指出:
经常提到的PHP5 OOP的一个关键点是“对象通过默认引用传递”。 这并不完全正确。 本节用一些例子来整理这个总体思想。
PHP引用是一个别名,它允许两个不同的variables写入相同的值。 从PHP5开始,对象variables不再包含对象本身的值。 它只包含一个对象标识符,允许对象访问者find实际的对象。 当一个对象被参数发送,返回或分配给另一个variables时,不同的variables不是别名:它们包含指向同一对象的标识符的副本。
有关更详细的解释(解释过分简化以及标识符),请查看此答案 。
从PHP手册 :
你可以通过引用一个函数来传递一个variables,这样函数可以修改这个variables。 语法如下:
<?php function foo(&$var) { $var++; } $a=5; foo($a); // $a is 6 here ?>
注意:在函数调用中没有参考符号 – 仅在函数定义上。 单独的函数定义足以通过引用正确地传递参数。 从PHP 5.3.0开始,当您在foo(&$ a);中使用&时,您会收到一条警告,指出“通过引用传递时间”已被弃用。
从PHP5的新function :
在PHP 5中,对象模型的基础结构被重写为与对象句柄一起工作。 除非使用clone关键字显式克隆对象,否则将永远不会在对象的场景重复之后创build对象。 在PHP 5中,既不需要通过引用来传递对象,也不需要通过引用来分配对象
所以,因此唯一需要使用function foo(&$var)
语法是$ var可能不是一个类的实例。
它似乎更精确一点,对象的值是通过值传递的,但是对象本身的值是一个指针。 这不同于传递参考。
在http://www.php.net/manual/en/language.oop5.references.php列出的例子很好。; 在第一组中,$ a = NULL; 不会影响$ b,因为$ a只是一个指针。 在第二组中,$ c = NULL; 导致$ d也是NULL,因为$ d是对$ c的引用。
<?php class A { public $foo = 1; } $a = new A; $b = $a; $a->foo = 2; $a = NULL; echo $b->foo."\n"; // 2 $c = new A; $d = &$c; $c->foo = 2; $c = NULL; echo $d->foo."\n"; // Notice: Trying to get property of non-object... ?>
从PHP 5开始,所有对象都通过引用来传递和分配。
在PHP 4中,您仍然需要通过明确使用&
运算符来指定希望引用传递的对象的位置。
简单的答案是肯定的 。 从对象和引用 :
经常提到的PHP5 OOP的一个关键点是“对象通过默认引用传递”。 这并不完全正确。 本节用一些例子来整理这个总体思想。
PHP引用是一个别名,它允许两个不同的variables写入相同的值。 从PHP5开始,对象variables不再包含对象本身的值。 它只包含一个对象标识符,允许对象访问器find实际的对象。 当一个对象被参数发送,返回或分配给另一个variables时,不同的variables不是别名:它们包含指向同一对象的标识符的副本。
重要的是,在你担心的情况下,除非在函数调用中明确使用clone关键字,否则永远不会制作对象的副本 。 无论是别名还是标识符都不会改变这一事实。
从PHP5开始,对象是通过引用传递的。 没有必要明确这样做。
http://www.php.net/manual/en/migration5.oop.php
在PHP 5中有一个新的对象模型。 PHP的对象处理已经被完全重写,可以获得更好的性能和更多的function。 在以前的PHP版本中,对象被处理为基本types(例如整数和string)。 这种方法的缺点是,在分配variables或作为parameter passing给方法时,语义上复制整个对象。 在新方法中,对象由句柄引用,而不是由值引起(可以将句柄看作对象的标识符)。
只是通过引用传递“对象”的例子是有用的:
class RefTest1 { public $foo; public function __construct(RefTest2 &$ref = null) { $this->foo =& $ref; } } class RefTest2 { public $foo; public function __construct(RefTest1 &$ref = null) { $this->foo =& $ref; } } class RefTest3 { public $foo; public function __construct(RefTest2 &$ref = null) { $this->foo =& $ref; } } class DoCrossRef { public $refTest1; public $refTest2; public function __construct() { $this->refTest1 = new RefTest1($this->refTest2); $this->refTest2 = new RefTest2($this->refTest1); } public function changeReference() { $this->refTest1 = new RefTest3($this->refTest2); } }
在RefTest1
保存了对RefTest2
的引用, RefTest2
,如果在RefTest2
对象不存在。
在调用DoCrossRef->changeReference()
, RefTest2
对象还包含对新RefTest3
对象的引用。