7

我有两个班级,“A”和“B”。在应用程序逻辑中,除了“A”类之外,不允许任何人创建“B”类对象。但是,由于我不想将这两个类放在同一个文件中,我不能用“私有”属性来限制它。

是否可以创建这种限制?如果“A”以外的其他人试图创建“B”类的对象,你说生气!?

4

5 回答 5

7

这就像它得到的一样hacky,你不应该使用它。我只发布它,因为我喜欢 hacky 的东西;)此外,如果E_STRICT启用错误报告,这将引发错误:

class B
{
    private function __construct() {}

    public function getInstance() {
        if (!isset($this) || !$this instanceof A) {
            throw new LogicException('Construction of B from a class other than A is not permitted.');
        }

        return new self;
    }
}

class A
{
    function someMethod() {
        $b = B::getInstance(); // note that I'm calling the non-static method statically!
    }
}

这样做的原因是一个“功能”,可以在本手册页的第二个示例中看到。

于 2010-10-15T16:34:44.330 回答
5

您可以检查回溯:

class B
{
    public function __construct()
    {
        $chain = debug_backtrace();
        $caller = $chain[1]['class'];

        if ('A' != $caller) {
            throw new Exception('Illegal instantiation');
        }
    }
}
于 2010-10-15T15:35:57.787 回答
0

在 B 的构造函数中,要求传入 A。当你想从 A 中获取 B 时,只需创建一个 B 并传入 A。当调用 new B 时,它会要求传入 A。

class A
{
    private $b;

    private function getB()
    {
        if (null === $this->b)
        {
            $this->b    = new B($this);
        }

        return $this->b;
    }
}

class B
{
    public function __construct(A $a)
    {

    }
}
于 2010-10-15T15:12:26.453 回答
0

也许你想使用这样的东西:

class A
{
        protected function __construct ()
        {
        }
}

class B extends A
{
        public function __construct ()
        {
                $a = new A();
        }
}

$b = new B();
于 2010-10-15T21:35:52.177 回答
-1

用于get_called_class找出哪个类试图实例化一个对象:

class B
{
        public function __construct ()
        {
                if(get_called_class() != 'A') {
                    //booboo
                }
        }
}
于 2010-10-16T00:29:36.663 回答