在 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 中如何通过引用传递对象?的主要内容,如果未能解决你的问题,请参考以下文章

PHP 数组的拷贝是按值传递 or 按引用传递

通过 const 引用传递对象?

php资源是通过引用传递的吗?

PHP对象到底是值传递还是引用传递

如何通过在 PHP 中通过引用传递变量来存储变量?

通过引用传递对象[重复]