php析构函数被调用两次

php析构函数被调用两次,php,destructor,Php,Destructor,有人能解释为什么父类析构函数被调用了两次吗?我的印象是,子类只能通过使用:parent::u 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 protecte

有人能解释为什么父类析构函数被调用了两次吗?我的印象是,子类只能通过使用:parent::u 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
 */
这仅适用于在子对象中重写_destruct方法的情况。例如:

//parent
public function __destruct() {
   echo 'goodbye from parent';
}
//child
public function __destruct() {
   echo 'goodbye from child';
}
。。。将输出:

goodbye from parentgoodbye from child
goodbye from parent
goodbye from child
然而,这:

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

goodbye from parentgoodbye from child
goodbye from parent
goodbye from child
如果不重写,它将隐式调用父析构函数。

您的hey类将从其父类继承u destruct方法。因此,当测试对象被销毁时,它被调用,当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(){
    }
}
然后,销毁消息将只输出一次

示例您的代码:

更改代码示例:

这里创建了两个对象。这两个都将在脚本结束时销毁

因为类hey没有定义析构函数方法,所以它调用父类进行析构函数。如果在子类中定义析构函数并运行代码,您将注意到它不再命中父类


但是您仍然看到test析构函数,因为您正在$obj=newtest行中创建一个test类型的对象。这是一个\arg\发送到test;的实例

这只是一种印象

与构造函数一样,引擎不会隐式调用父析构函数。为了运行父析构函数,必须在析构函数体中显式调用parent::u 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();

似乎您正试图在hey中访问来自测试类$test3的私有变量,这意味着hey类像bug一样继承了它的外观,因为php文档说析构函数的工作方式与构造函数的工作方式类似,除非子级使用parent::否则子级不会调用析构函数,在我的示例中,继承子级确实不会调用父级构造函数,但析构函数似乎忽略了文档中的内容say@zero否,它仅在重写该方法时适用。上述情况也适用于_构造函数:如果子类定义了构造函数,则不会隐式调用父构造函数。是的,你是对的,但看起来很奇怪。在大多数其他oop风格的语言中是这样的还是php的东西?@zero我不确定-Java没有析构函数,其构造函数的工作方式是相同的,但在Java中,您需要调用与parent::\u construct等价的函数