2012-07-19 126 views
5

可能重复:
In PHP can someone explain cloning vs pointer reference?如果对象通过别名传递,您何时通过引用传递?

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

一个经常被提到的PHP 5 OOP的关键点之一是“对象是通过传递默认引用“。这并不完全正确。本节使用一些例子来整理这个一般思想。

PHP引用是一个别名,它允许两个不同的变量写入相同的值。从PHP 5开始,对象变量不再包含对象本身的值。它只包含一个对象标识符,它允许对象访问器找到实际的对象。当对象是由参数,返回或分配给另一个变量发送时,不同的变量不是别名:其所持有的标识符,它指向相同的对象的副本。

如果对象通过别名或处理程序传递,那么在什么情况下你真的想通过引用传递?

myFunc($obj); // Pass by alias/handler 

myFunc(& $obj); // Pass by reference (when would you do this?) 

myFunc(clone $obj); // Create a new object 

这些每种情况的不同用例有哪些?

+2

我认为这个讲座涵盖了以下主题:http://www.youtube.com/watch?v = bxxIXPc9IR8(其中包括) – 2012-07-19 15:13:24

+2

请注意,从至少5.3开始,呼叫时传递引用已被弃用,如果不是更早。该函数声明了ARG游戏,预计将引用,并调用者没有指定,他们是引用 - 和,其实不应该。 – cHao 2012-07-19 15:16:39

回答

2

这些中每一个的不同用例是什么?

您已经命名了三种不同的使用情况:

  1. 传递一个对象作为参数
  2. 传递一个别名作为参数
  3. 传递对象克隆作为参数

当你需要做具体案例时,你自然会做这三件事中的每一件。你通常只需要99.9%的1。当你需要时你做另外的0.1%。

一种examlary用例(如在注释要求)的用于可变别名作为参数作为一个小例子(Demo):

class VarFreezer 
{ 
    private $alias; 
    private $value; 
    public function __construct(&$object) { 
     $this->alias = &$object; 
     $this->value = $object; 
    } 
    public function restore() 
    { 
     $this->alias = $this->value; 
    } 
} 

$var = new stdClass(); 
$var->value = 'I am an object now.'; 

$freezer = new VarFreezer($var); 

$var = 'I am a string now.'; 

$freezer->restore(); 

var_dump($var); 
+0

任何想法'myFunc(&$ obj)'的具体用例是什么? – 2012-07-19 15:20:25

+0

这是特别传递一个变量别名作为参数。所以你可以用第二个名字引用同一个变量。 – hakre 2012-07-19 15:22:09

+0

@Dev我特别提到当传入函数时对象及其行为 - 而不是像字符串这样的基本类型。 – 2012-07-19 15:24:35

2

当你给一个目的是一种方法的参考现有传递对象以便调用作用域中的变量和方法作用域中的方法参数变量都引用同一个对象。

您可以明确地使用&来引用像数组这样的原语,以便调用的方法可以更改原始数组的数据。对于这个对象来说,这是现在你所提到的默认值。

一个克隆似乎很明显。

With & $ obj您为$ obj创建一个别名而不是对象的引用$ obj引用。引用php。网:

$c = new A; 
$d = &$c; 
$c->foo = 2; 
$c = NULL; 
echo $d->foo."\n"; // Notice: Trying to get property of non-object... 
2

MYFUNC($ OBJ)//传递标识

当你的功能需要获得访问对象和操作/从中读取莫名其妙。

myfunc(& $ obj)//传递参考标识符。

这里的关键在于你传递了对标识符的引用。这意味着如果外部变量($ obj)设置为null,那么内部对象也会变为null,因为您已经从$ obj中删除了标识符,因此对它的引用也被删除。不像当你在标识符传递,因为你的实际去做传入标识符的副本,因此,如果$的obj设置为null,则该函数将仍然指向对象内的值。

例如:

var x = new Object(); 

var y = x //y and x both contain **different** identifiers to the same object in memory. 

function a($_a){} // a function for examples 

a($y) // passes in a copy of $y so $_a (inside the function) is a third identifier pointing to th in memory object 

a(& $y) // now $_a contains the **same** identifier as $y so if either is emptied then the other is also emptied. 

a(clone $y) //creates a new object identical to the first and passes in an identifier of the new object. 

希望多数民众赞成清楚。

你会被引用,如果您希望能够从函数内部修改或删除标识,并有其影响外部标识变量同时能够返回一个独立计算值传递的标识符。例如序列化一个对象,将其保存到文件中返回文件字符串,但也要清除标识符,以便可以从内存中清除该对象。