有人可以解释为什么父类析构函数被调用两次?我的印象是,子类只能通过使用: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
*/
答案 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)
它只是一种印象......
与构造函数一样,父析构函数不会被引擎隐式调用 。为了运行父析构函数,必须在析构函数体中显式调用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();