Prevent destructor from being called manually

你。 提交于 2019-12-11 23:24:54

问题


I have this class:

class Test
{
    private $test = 'ok';

    public function doTest()
    {
        echo $this->test;
    }

    public function __destruct()
    {
        $this->test = 'not ok';
    }
}

and the following test case:

$test = new Test;
$test->__destruct(); // I wish this would throw a Fatal Error or something...
$test->doTest(); // prints "not ok"

What I want to accomplish is to prevent __destruct() from being called manually, so that doTest() will never print "not ok".

I tried setting the destructor's visibility to private, but that just leads to a Fatal Error on object destruction. An option would be to set a flag $this->destructed in the destructor and then throw an Exception in doTest() if this flag is true, but it wouldn't be very efficient to check for this flag every time the method is called.

So, a private destructor is not possible and a flag $this->destructed is ugly. Are there better ways?


回答1:


If you don't want the destructor to be called, don't implement it. Instead, use a private delegate to do the shutdown stuff.

Your class:

class Test
{
    private $delegate;

    public function __construct()
    {
        $this->delegate = new TestDelegate;
    }

    public function doTest()
    {
        echo $this->delegate->test."\n";
    }
}

Delegate:

class TestDelegate
{
    public $test = 'ok';

    public function __destruct()
    {
        $this->test = 'not ok';
        echo __METHOD__." called\n";
    }
}

Test:

$test = new Test;
//$test->__destruct(); // fatal error
$test->doTest(); // prints "ok"
// TestDelegate::__destruct() gets called automatically

Now, this may introduce other problems. How to make sure the delegate gets registered if a child class implements a constructor and forgets to call its parent constructor? And wouldn't it break things if the constructor gets called multiple times?

To deal with that, make the constructor final and private and use a factory method:

public static function create()
{
    return new static;
}


来源:https://stackoverflow.com/questions/20808882/prevent-destructor-from-being-called-manually

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!