2017-09-23 140 views
1

我不明白如何從函數返回對象。由於對象是通過引用傳遞和返回的,所以如果我在函數中創建了一個對象,我希望這個對象在函數完成執行後被銷燬。所以這種返回的對象引用應該指的是不存在的(被銷燬的)對象。但是我在函數內創建的對象已成功返回。怎麼來的??函數如何返回一個對象?

class O{ 
    public $ppty = "ppty value"; 
} 

function f1(){ 
    $o1 = new O(); 
    return $o1; 
} 

var_dump(f1()); 


**Result:** 
object(O)[15] 
    public 'ppty' => string 'ppty value' (length=10) 
+3

對象生存期未連接到變量生存期。 –

+0

@ IgnacioVazquez-Abrams有什麼文件可以向我推薦這件事嗎? –

回答

5

變量「持有」一個對象實際上是持有對該對象的引用。該對象存在於內存中的某處,引用該對象的變量只保存內存地址(過於簡化)。 這就是的參考。當返回引用或將其傳遞給另一個變量時,將引用該引用的副本(意思是複製內存地址值;例如,您從函數中返回值0xDEADBEAF;再次簡化)。這些引用被視爲對象的屬性;只有當引用計數達到0(沒有變量持有對該對象的引用時),才收集對象垃圾。

2

考慮下面的例子:

$var = 'test'; 
$ref = &$var; 
unset($ref); 
echo $var; // Echoes "test". 

的未設置僅去除$var提及$ref,不破壞原始變量$ref指。這與您作爲引用對象的示例類似,垃圾收集只會刪除變量對該對象的引用,但對象仍然存在於內存中。

有關更多詳細信息,請參見http://php.net/manual/en/language.references.unset.php

1

當應用程序的功能或範圍完成時,不再可訪問的局部變量將被刪除。但是,當您從一個類創建對象時,場景是不同的。它們不會被自動刪除,在PHP中有一個垃圾收集器,它不斷地搜索不再可訪問的對象,並且如果它發現它會刪除它們。

所以當你從函數返回對象引用時,它不會被刪除。如果您不會將參考存儲在任何變量中,GC將在稍後刪除。

有關垃圾收集器在PHP更多的信息,請閱讀此鏈接:

http://php.net/manual/en/features.gc.refcounting-basics.php

0

在PHP中所有的值存儲在變量容器。這些zvals包含實際的數據和類型信息。結帳出下面的例子。

<?php 

class O{ 
    public $ppty = "ppty value"; 
} 

$a = new 0; // $a is pointing to zval(class 0) with refcount 1 
$b = $a; // $a and $b are pointing to zval(class 0) with refcount 2 
$c = $b; // $a, $b and $c are pointing to zval(class 0) with refcount 3 

unset($a) // new $b and $c are pointing to zval(class 0) with refcount 2 

// until the refcount is greater then the 0 the destructor will not called 
?> 

現在就來看看下面的例子

<?php 

$a = new 0; // $a is pointing to zval(class 0) with refcount 1 

unset($a) // here refcount is 0 and destruct will be called 

?> 

現在來看看你的例子

<?php 

function f1(){ 
    $o1 = new O(); // refcount = 1 
    return $o1; 
} 

// now you are returning the object in function f1 and so, 
// $o1 is gone after the function scope but the func f1 is now pointing the its reference. 


var_dump(f1()) 


**Result:** 
object(O)[15] 
    public 'ppty' => string 'ppty value' (length=10) 

//一旦這個過程完成,然後它會調用銷燬。