2012-08-30 56 views
5

可能重複:
what is Object Cloning in php?PHP克隆關鍵字

我學習一個現有的架構,它採用「克隆」關鍵詞很多,不知道這是否是一個好主意,做這個 ?我真的不明白需要使用'克隆'關鍵字。

例如在這種編碼

public function getStartDate() 
    { 
    return clone $this->startDate; 
    } 

給我這個功能應該是像下面有看,我沒有看到克隆的需要。

public function getStartDate() 
    { 
    return $this->startDate; 
    } 
+0

的[原型設計模式](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref = sr_1_1)也是一個很好的用例。 – pce

回答

6

使用克隆的原因是PHP使用對象時總是返回對象作爲引用,而不是副本。

這就是爲什麼傳遞對象的功能,當你不需要用&(參考)指定:

function doSomethingWithObject(MyObject $object) { // it is same as MyObject &object 
    ... 
} 

因此,爲了獲得對象複製,你必須使用clone關鍵字 這是如何對象的例子是由PHP來處理,什麼克隆做:

class Obj { 
    public $obj; 
    public function __construct() { 
     $this->obj = new stdClass(); 
     $this->obj->prop = 1; // set a public property 
    } 
    function getObj(){ 
     return $this->obj; // it returns a reference 
    } 
} 

$obj = new Obj(); 

$a = $obj->obj; // get as public property (it is reference) 
$b = $obj->getObj(); // get as return of method (it is also a reference) 
$b->prop = 7; 
var_dump($a === $b); // (boolean) true 
var_dump($a->prop, $b->prop, $obj->obj->prop); // int(7), int(7), int(7) 
// changing $b->prop didn't actually change other two object, since both $a and $b are just references to $obj->obj 

$c = clone $a; 
$c->prop = -3; 
var_dump($a === $c); // (boolean) false 
var_dump($a->prop, $c->prop, $obj->obj->prop); // int(7), int(-3), int(7) 
// since $c is completely new copy of object $obj->obj and not a reference to it, changing prop value in $c does not affect $a, $b nor $obj->obj! 
0

,儘管它在another question(感謝指出這@gerald)

只是一個快速的答案perfectley解釋說:

沒有克隆的函數返回到起始日期對象的引用。用克隆它返回一個副本。

如果返回的對象稍後將被更改,它只會更改副本,而不是原來的,這可能也會在其他地方使用。

+0

但問題是在完全面向對象的設計中,我們需要將實際對象傳遞給克隆對象,是不是這樣?對我來說,使用克隆對象的這種設計在OO設計實踐中使用時會在類中增加。 – mahen3d

3

也許startDate是一個對象。

然後。當您返回clone $this->startDate時 - 您將獲得該對象的完整副本。你可以玩它,改變價值,調用功能。並且,直到它們影響數據庫或文件系統 - 它是安全的,並且實際的對象不會被修改。

但是,如果你只是返回對象 - 你只返回一個引用。和任何對象操作一樣 - 你可以用原始對象進行這個操作。您所做的任何更改 - 這將影響startDate

這僅適用於對象,不會影響數組,字符串和數字,因爲它們是值類型變量。

您應該詳細瞭解值類型變量和引用類型變量。