防止析构函数被手动调用 [英] Prevent destructor from being called manually

查看:180
本文介绍了防止析构函数被手动调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个课程:

class Test
{
    private $test = 'ok';

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

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

和以下测试用例:

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

我要完成的工作是防止 __destruct()不会被手动调用,因此 doTest()永远不会打印不好。

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

我尝试将析构函数的可见性设置为 private ,但这只会导致对象破坏的致命错误。一种选择是在析构函数中设置标志 $ this-> destructed ,然后在 doTest()如果此标志为true,但是每次调用该方法时都必须检查该标志。

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.

因此, private 析构函数是不可能的,并且 $ this-> destructed 的标志是丑陋的。有更好的方法吗?

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

推荐答案

如果您不希望调用析构函数,则不要实现它。而是使用 private 委托来执行关闭操作。

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

您的课程:

class Test
{
    private $delegate;

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

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

委托:

class TestDelegate
{
    public $test = 'ok';

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

测试:

$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?

要解决这个问题,请使构造函数 final private 并使用工厂方法:

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

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

这篇关于防止析构函数被手动调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆