2012-12-03 199 views
0

有人可以解釋爲什麼父類析構函數被調用兩次嗎?我的印象是,一個子類只能使用調用父的析構函數:父:: __自毀()php析構函數被調用兩次

class test { 

    public $test1 = "this is a test of a pulic property"; 
    private $test2 = "this is a test of a private property"; 
    protected $test3 = "this is a test of a protected property"; 
    const hello = 900000; 

    function __construct($h){ 
     //echo 'this is the constructor test '.$h; 
    } 

    function x($x2){ 
     echo ' this is fn x'.$x2; 
    } 
    function y(){ 
     print "this is fn y"; 
    } 

    function __destruct(){ 
     echo '<br>now calling the destructor<br>'; 
    } 
} 

class hey extends test { 

    function hey(){ 
     $this->x('<br>from the host with the most'); 
     echo ' <br>from hey class'.$this->test3; 
    } 
} 

$obj = new test("this is an \"arg\" sent to instance of test"); 
$obj2 = new hey(); 
echo $obj2::hello; 
/* 
the result: 
this is fn x 
from the host with the most 
from hey classthis is a test of a protected property900000 
now calling the destructor 

now calling the destructor 
*/ 
+0

看來你正試圖從測試類 –

+0

$ TEST3被保護在好端端的一個私有變量訪問什麼然後意思是hey類繼承了它 – zero

回答

4

這隻有在__destruct方法在孩子重寫應用。例如:

//parent 
public function __destruct() { 
    echo 'goodbye from parent'; 
} 
//child 
public function __destruct() { 
    echo 'goodbye from child'; 
} 

... ...將輸出:

goodbye from parentgoodbye from child 

然而,這樣的:

//child 
public function __destruct() { 
    echo parent::__destruct() . "\n"; 
    echo 'goodbye from child'; 
} 

將輸出:

goodbye from parent 
goodbye from child 

如果不重寫,它隱含地調用父析構函數。

+0

看起來像一個bug,因爲php文檔說析構函數的作用就像構造函數一樣,除非孩子使用「parent ::」,否則他們不會被孩子調用http://php.net/ manual/en/language.oop5.decon.php,這是真的,父構造函數不被inh調用在我的例子中冒用了孩子,但是析構函數似乎忽略了文檔所說的 – zero

+0

@零不,它只適用於方法被覆蓋的情況。上面同樣適用於'__construct'或者:「如果子類定義了構造函數,父構造函數不會隱式調用。 –

+0

是的,你是對的,雖然看起來很奇怪。是這樣的在大多數其他的OOP風格的語言或是一個PHP的東西? – zero

1

您的hey類從其父項繼承__destruct方法。所以,當test對象被銷燬時,它被調用,並且當hey對象被銷燬時,它會被再次調用。

考慮這種變化:

class hey extends test{ 
    function hey(){ 
     $this->x('<br>from the host with the most'); 
     echo ' <br>from hey class'.$this->test3; 
    } 

    function __destruct(){ 
    } 
} 

然後,你的毀滅消息僅輸出一次。

樣品(代碼):http://codepad.org/3QnRCFsf

樣品(改變密碼):http://codepad.org/fj3M1IuO

4
$obj = new test("this is an \"arg\" sent to instance of test"); 
$obj2 = new hey(); 

你已經被這裏創建了兩個對象。這兩個都會在腳本結尾處毀壞。

由於hey類沒有定義一個destruct方法,所以它會調用父級別的destruct。如果你在子類中定義一個destruct並運行你的代碼,你會注意到它不再碰到父類。

但是您仍然看到test毀壞,因爲您正在$obj = new test("this is an \"arg\" sent to instance of test");行中創建類型爲test的對象。

1

它唯一的印象....

The PHP DOC On Destructor

構造函數一樣,父析構函數不會被隱含發動機調用。爲了運行父析構函數,必須在析構函數體中顯式調用parent :: __ destruct()。

即使使用exit()停止腳本執行,析構函數也會被調用。在析構函數中調用exit()將阻止其餘的關閉例程執行。

如果你沒有,你需要覆蓋它

class test { 
    function __destruct() { 
     var_dump(__CLASS__); 
    } 
} 
class hey extends test { 

    function __destruct() { // <------ over write it 
    } 
} 
$obj = new test(); 
$obj2 = new hey();