防止析构函数被手动调用

时间:2013-12-27 22:49:27

标签: php oop destructor

我有这堂课:

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()永远不会打印“不行”。

我尝试将析构函数的可见性设置为private,但这只会导致对象破坏时出现致命错误。一个选项是在析构函数中设置一个标志$this->destructed,如果这个标志为真,则在doTest()中抛出一个Exception,但是每次方法检查这个标志都不是很有效被称为。

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

1 个答案:

答案 0 :(得分:0)

如果您不想调用析构函数,请不要实现它。相反,使用private委托来执行关闭操作。

你的班级:

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

现在,这可能会引入其他问题。如果子类实现构造函数并忘记调用其父构造函数,如何确保委托被注册?如果多次调用构造函数,它会不会破坏它?

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

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