0

有人可以解释为什么父类析构函数被调用两次吗?我的印象是子类只能通过使用来调用父类的析构函数: 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

4 回答 4

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

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

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

但是您仍然看到test破坏,因为您test在 line 中创建了一个类型的对象$obj = new test("this is an \"arg\" sent to instance of test");

于 2012-12-03T17:37:15.420 回答
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

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

于 2012-12-03T17:32:26.163 回答
1

它只是一个印象....

关于析构函数的 PHP 文档

与构造函数一样,父析构函数不会被引擎隐式调用。为了运行父析构函数,必须在析构函数体中显式调用 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();
于 2012-12-03T17:38:25.767 回答
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

于 2012-12-03T17:32:37.973 回答