这让我想起了baboushka的
当然,你一定会在这里得到无限递归。两个函数相互调用,每次返回一个新实例,将调用的返回值传递给它们的函数计数器部分,然后再次调用该函数,该函数再次调用另一个函数,该函数调用....
底线:当您有 2 个从一开始就相互依赖的类 ( __construct
) 时,您的设计可能存在缺陷。
您定义这两个构造函数的方式,您将永远无法创建类的实例。仅仅是因为您需要同时实例化两个类。
你不能,你根本不能那样做。
尝试这个:
class A
{
public $b = null;
public function __construct(B $b = null)
{
$this->b = $b;
}
public function setB(B $b = null)
{
if ($b === null)
{
$b = new B($this);//pass A here
}
$this->b = $b;
return $this;
}
}
class B
{
public $a = null;
public function __construct(A $a = null)
{
$this->setA($a);
}
public function setA(A $a = null)
{
if ($a === null)
{
$a = new A($this);//pass B here
}
$this->a = $a;
return $this;
}
}
通过将构造函数参数的默认值设置为null
,传递一个实例就变成了可选的,所以现在你可以这样做:
$a = new A;
$b = new B($a);
//or even:
$bFromA = $a->b;
顺便说一句:总是事先声明你的属性。它会加快你的课。
就个人而言,我会使用 getter和setter,并延迟加载依赖项,但我会保持构造函数原样:
class A
{
//protected, or private. Access this via getter/setter
protected $b = null;
public function __construct(B $b = null)
{
$this->setB($b);
return $this;
}
//setter, allows injection later on
public function setB(B $b = null)
{
$this->b = $b;//allow to set to null
return $this;
}
//getter, lazy-loader:
public function getB()
{
if ($this->b === null)
{//create new instance, if b isn't set
$this->setB(
new B($this)
);
}
return $this->b;
}
}
class B
{
protected $a = null;
public function __construct(A $a = null)
{
$this->setA($a);
return $this;
}
public function setA(A $a = null)
{
$this->a = $a;
return $this;
}
public function getA()
{
if ($this->a === null)
{
$this->setA(
new A($this)
);
}
return $this->a;
}
}
使用疙瘩:
$c['aService'] = function($c)
{
return new A;
};
$c['bService'] = function($c)
{
return new B;
};
$b = $c->bService;
$b->getA();//works just fine