我似乎无法得到任何一致的信息。不同的来源似乎说不同的东西和古老的php.net本身(出现)不明确说明这一点 - 虽然,我必须承认,我只是快速看一下。
如果我在传递'重'对象,我需要通过引用传递,但我不想继续输入:
function foo(TypeName& $obj)
如果我能完全逃脱
function foo(TypeName $obj)
那么标准说的是什么?
答案 0 :(得分:89)
通过引用传递(和分配)对象。无需使用运营商的地址。
当然,我输入的内容过于简单,但适合您的目的。 documentation州:
PHP5 OOP的关键点之一 经常提到的是“对象 默认情况下通过引用传递“。 这不完全正确。这个 部分纠正了一般的思想 使用一些例子。
PHP引用是别名,它是 允许两个不同的变量 写入相同的值。从PHP5开始, 对象变量不包含 将自己视为价值。它 仅包含对象标识符 它允许对象访问者查找 实际的对象。当一个物体是 通过参数发送,返回或分配 到另一个变量,不同 变量不是别名:它们持有一个 标识符的副本,指向哪个 同一个对象。
有关更详细的说明(解释过度简化和标识符),请查看this answer。
答案 1 :(得分:8)
来自PHP manual:
您可以通过引用传递变量 一个功能所以功能可以 修改变量。语法如下 如下:
<?php function foo(&$var) { $var++; } $a=5; foo($a); // $a is 6 here ?>
注意:a上没有参考标记 函数调用 - 仅在函数上 定义。功能定义 单独就足以正确传递 参考的论点。截至PHP 5.3.0,你会收到一条警告说“通过参考传递通话”是 使用&amp;时弃用在 FOO(安培; $ A);
在PHP 5中,基础设施 对象模型被重写为工作 带有对象句柄。除非你 使用显式克隆对象 你永远不会克隆的关键字 在场景后面创建重复的 你的对象。在PHP 5中,有 既不需要传递对象 引用或分配它们 参考
因此,您需要使用function foo(&$var)
语法的唯一时间是$ var可能不是类的实例。
答案 2 :(得分:5)
似乎更精确一点,对象的值是按值传递的,但对象本身的值是一个指针。这与传递引用不同。
在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...
?>
答案 3 :(得分:3)
从PHP 5开始,所有对象都通过引用传递和分配。
在PHP 4中,您仍然需要通过显式使用&
运算符来指定通过引用传递对象的位置。
答案 4 :(得分:2)
简短回答是。来自Objects and references:
PHP5 OOP的关键点之一 经常提到的是“对象 默认情况下通过引用传递“。 这不完全正确。这个 部分纠正了一般的思想 使用一些例子。
PHP引用是别名,它是 允许两个不同的变量 写入相同的值。从PHP5开始, 对象变量不包含 将自己视为价值。它 仅包含对象标识符 它允许对象访问者查找 实际的对象。当一个物体是 通过参数发送,返回或分配 到另一个变量,不同 变量不是别名:它们持有一个 标识符的副本,指向哪个 同一个对象。
重要的是,在您担心的情况下,除非您在函数调用中明确使用 clone 关键字,否则您永远不会复制对象。无论是别名还是标识符都不会改变这一事实。
答案 5 :(得分:2)
只是传递&#34;对象&#34;通过引用是有用的:
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
时RefTest1
对象不存在。< / p>
调用DoCrossRef->changeReference()
后,RefTest2
个对象也会保留对新RefTest3
对象的引用。
答案 6 :(得分:1)
从PHP5起,是的,对象通过引用传递。无需明确地做到这一点。
http://www.php.net/manual/en/migration5.oop.php
在PHP 5中有一个新的对象模型。 PHP对对象的处理已经完全重写,允许更好的性能和更多的功能。在以前的PHP版本中,对象的处理方式与原始类型(例如整数和字符串)相同。这种方法的缺点是语义上整个对象在分配变量时被复制,或者作为参数传递给方法。在新方法中,对象由句柄引用,而不是通过值引用(可以将句柄视为对象的标识符)。
答案 7 :(得分:0)
这是另一个确认对象通过引用传递的示例。
<?php
// discussion: https://stackoverflow.com/questions/2715026/are-php5-objects-passed-by-reference#_=_
class A {
public $foo = 1;
}
class B {
function inc($obj) {
$obj->foo++;
}
}
$objA = new A();
$objB = new B();
$objB->inc($objA);
echo "[" . $objA->foo . "]"; // Outputs [2]