php析构函数被调用两次

时间:2012-12-03 17:26:54

标签: php destructor

有人可以解释为什么父类析构函数被调用两次?我的印象是,子类只能通过使用:parent :: __ destruct()

来调用父类的析构函数
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
 */

4 个答案:

答案 0 :(得分: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

如果不覆盖,则会隐式调用父析构函数。

答案 1 :(得分:4)

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

您在这里创建了两个对象。这两个都将在你的脚本结束时破坏。

由于类hey没有定义destruct方法,因此它调用父类来进行析构。如果你在子类中定义了一个destruct并运行你的代码,你会注意到它不再命中父类。

但您仍然看到test销毁,因为您在test行中创建了$obj = new test("this is an \"arg\" sent to instance of test");类型的对象。

答案 2 :(得分: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(){
    }
}

然后,你的destruct消息只输出一次。

示例(您的代码):http://codepad.org/3QnRCFsf

示例(已更改的代码):http://codepad.org/fj3M1IuO

答案 3 :(得分: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();