Php Destruct被称为两次

Pau*_*ton 3 php oop destructor

下面的代码说明了两次调用destruct().我想知道为什么?

class A {
    function hi(){ echo 'hi'; }
    function __destruct(){
        echo 'destroy';
    }
}
class B{
    public $this_ = '';
    function __construct(){
        $this->this_ = new A;
    }
    function __call($method, $params) {
          return call_user_func_array(array($this->this_, $method), $params);
    }
}

$b = new B;
$b->__destruct();
Run Code Online (Sandbox Code Playgroud)

输出:

destroydestroy
Run Code Online (Sandbox Code Playgroud)

编辑

zneak和TomcatExodus都是正确的.如果我只是:

[..code..]
$b = new B;
$b->__destruct();
print 'end of script';
Run Code Online (Sandbox Code Playgroud)

输出将显示:

destroyend of scriptdestroy
Run Code Online (Sandbox Code Playgroud)

Dan*_*ugg 13

调用destruct不会破坏对象.你__destruct()第一次调用它,然后当PHP脚本终止时,它会在清理时再次调用它.

如果您希望在脚本终止之前销毁该对象,unset()那么.你应该只看到一次破坏性调用.


具体来说,您的类B创建一个自包含的类实例A.由于B还路由方法通过调用__call()A对象,这就是为什么一个__destruct()随叫随到B呼吁__destruct()A; B没有定义析构函数并通过调用.

  • @Ben:不完全; zneak有正确的细节. (2认同)

zne*_*eak 10

由于B没有__destruct方法,因此__call调用该方法(您可以通过添加类似于echo "calling $method"您的__call方法的方法来验证此方法),然后将其转发到您的A对象.

但是,调用__destruct不会破坏对象:它只调用应该与其销毁相关联的清理代码.因此,一旦到达脚本的末尾,当A对象实际被销毁时​​,将__destruct再次调用其方法.

如果要删除B对象,请使用unset($b).