2012-07-19 210 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. 

希望多數民衆贊成清楚。

你會被引用,如果您希望能夠從函數內部修改或刪除標識,並有其影響外部標識變量同時能夠返回一個獨立計算值傳遞的標識符。例如序列化一個對象,將其保存到文件中返回文件字符串,但也要清除標識符,以便可以從內存中清除該對象。