我有两个班级,“A”和“B”。在应用程序逻辑中,除了“A”类之外,不允许任何人创建“B”类对象。但是,由于我不想将这两个类放在同一个文件中,我不能用“私有”属性来限制它。
是否可以创建这种限制?如果“A”以外的其他人试图创建“B”类的对象,你说生气!?
我有两个班级,“A”和“B”。在应用程序逻辑中,除了“A”类之外,不允许任何人创建“B”类对象。但是,由于我不想将这两个类放在同一个文件中,我不能用“私有”属性来限制它。
是否可以创建这种限制?如果“A”以外的其他人试图创建“B”类的对象,你说生气!?
这就像它得到的一样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!
}
}
这样做的原因是一个“功能”,可以在本手册页的第二个示例中看到。
您可以检查回溯:
class B
{
public function __construct()
{
$chain = debug_backtrace();
$caller = $chain[1]['class'];
if ('A' != $caller) {
throw new Exception('Illegal instantiation');
}
}
}
在 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)
{
}
}
也许你想使用这样的东西:
class A
{
protected function __construct ()
{
}
}
class B extends A
{
public function __construct ()
{
$a = new A();
}
}
$b = new B();
用于get_called_class
找出哪个类试图实例化一个对象:
class B
{
public function __construct ()
{
if(get_called_class() != 'A') {
//booboo
}
}
}