在 PHP 5 中如何通过引用传递对象?
Posted
技术标签:
【中文标题】在 PHP 5 中如何通过引用传递对象?【英文标题】:How do you pass objects by reference in PHP 5? 【发布时间】:2012-03-09 01:05:55 【问题描述】:在 php 5 中,是否需要使用 &
修饰符才能通过引用传递?例如,
class People()
$p = new People();
function one($a) $a = null;
function two(&$a) $a = null; )
在 PHP4 中,您需要 &
修饰符在进行更改后维护引用,但我对我读过的关于 PHP5 自动使用传递引用的主题感到困惑,除非明确克隆对象.
在 PHP5 中, &
修饰符是否需要通过引用传递所有类型的对象(变量、类、数组等)? p>
【问题讨论】:
本手册将解决您的所有问题。 php.net/manual/en/language.oop5.references.php 【参考方案1】:是否需要使用 & 修饰符来传递引用?
从技术/语义上来说,答案是是的,即使是对象也是如此。这是因为有两种方法可以传递/分配对象:通过引用或通过标识符。当函数声明包含&
时,如:
function func(&$obj)
无论如何,参数都将通过引用传递。如果你声明没有&
function func($obj)
一切都将通过值传递,除了对象和资源,它们将通过标识符传递。什么是标识符?好吧,您可以将其视为对引用的引用。举个例子:
class A
public $v = 1;
function change($obj)
$obj->v = 2;
function makezero($obj)
$obj = 0;
$a = new A();
change($a);
var_dump($a);
/*
output:
object(A)#1 (1)
["v"]=>
int(2)
*/
makezero($a);
var_dump($a);
/*
output (same as before):
object(A)#1 (1)
["v"]=>
int(2)
*/
那么为什么$a
在传递给makezero
之后不会突然变成一个整数呢?这是因为我们只覆盖了标识符。如果我们通过了reference:
function makezero(&$obj)
$obj = 0;
makezero($a);
var_dump($a);
/*
output:
int(0)
*/
现在$a
是一个整数。所以,通过identifier和通过reference是有区别的。
【讨论】:
感谢您解释标识符和引用之间的区别,手册对此不是很清楚。 这也是javascript对象默认传递的方式。 很抱歉,您能否澄清一下为什么 change() 起作用而不是 makezero()?你错过了一个 & 登录 change() 吗?另外我认为在 makezero 你想改变 $obj = 0;到 $obj->v = 0 在我的脑海中总结和排序所有这些:除非用 & 明确引用,否则不是对象或资源的所有内容都按值传递,对吧?默认情况下,对象和资源通过标识符传递。我们可以将“标识符”视为“别名”的同义词,对吗? “别名”可以用来操作对象,但它不是对象。【参考方案2】:对象将通过引用传递。内置类型将通过值传递(复制);
幕后发生的事情是,当您传入一个包含对象的变量时,它是对该对象的引用。所以变量本身被复制了,但它仍然引用同一个对象。所以,本质上有两个变量,但都指向同一个对象。对函数内对象所做的更改将保持不变。
如果你有那里的代码(首先你需要 $ 甚至 &):
$original = new Object();
one($original); //$original unaffected
two($original); //$original will now be null
function one($a) $a = null; //This one has no impact on your original variable, it will still point to the object
function two(&$a) $a = null; ) //This one will set your original variable to null, you'll lose the reference to the object.
【讨论】:
所以整数、字符串、字符和布尔值都是按值传递的,除非使用&
修饰符?
@BrianGraham 是的。如果您熟悉 C/C++ 中的指针,前面示例中的 $original 就是这样。它保存了我们创建的对象的地址。 $original 本身在传递给函数 one($a) 时会被复制,但由于它拥有一个地址,因此副本指向的是同一个 Object。
你说PHP5中的对象是通过引用传递的,对吧?那你为什么要使用&
修饰符来证明你的观点,如果不需要的话,它并不能帮助我理解我的问题。
对象实际上并不是通过引用传递的。变量和对象之间的相等本质上传递了对它的引用。在函数调用期间同样的按值传递操作,即 $obj=$passedObject 结果 $obj=&passedObjects
@SomeshMukherjee 我的理解是 $obj = $passedObject,如果我们设置 $obj = null,$passedObject != null。但是如果 $obj = &$passedObject 并且你设置了 $obj = null,现在 $passedObject == null。【参考方案3】:
你用错了。 $ 符号对于任何变量都是强制性的。它应该是: http://php.net/manual/en/language.references.pass.php
function foo(&$a)
$a=null;
foo($a);
To return a reference, use
function &bar($a)
$a=5;
return $a
在对象和数组中,对对象的引用被复制为形参,对两个对象的任何相等操作都是引用交换。
$a=new People();
$b=$a;//equivalent to &$b=&$a roughly. That is the address of $b is the same as that of $a
function goo($obj)
//$obj=$e(below) which essentially passes a reference of $e to $obj. For a basic datatype such as string, integer, bool, this would copy the value, but since equality between objects is anyways by references, this results in $obj as a reference to $e
$e=new People();
goo($e);
【讨论】:
我忘记了$
符号,抱歉。以上是关于在 PHP 5 中如何通过引用传递对象?的主要内容,如果未能解决你的问题,请参考以下文章