1

我有视对方两类:PHP疙瘩交叉依赖

class A 
{ 
    public function __construct(B $b) 
    { 
     $this->b = $b; 
    } 
} 
class B 
{ 
    public function __construct(A $a) 
    { 
     $this->a = $a; 
    } 
} 

我需要通过疙瘩来包装他们是这样的:

$c = new \Pimple(); 
$c['aService'] = function($c){ 
    return new A($c['bService']); 
} 
$c['bService'] = function($c){ 
    return new B($c['aService']); 
} 

但不幸的是,我得到循环:

Fatal error: Maximum function nesting level of '100' reached, aborting! 

有没有办法在没有骑车的情况下达到这种交叉依赖?或者我只能使用单向依赖关系?

回答

1

这让我想起了baboushka的

你一定会在这里得到无限递归当然。两个函数互相调用,每次都返回一个新的实例,它将调用的返回值传递给它们的函数计数器部分,函数计数器部分再次调用该函数,再次调用另一个函数,调用....
底线:当你有两个相互依赖的课程(__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; 

BTW :总是事先声明您的属性。 It'll speed up your classes

就个人而言,我会使用一个getter 一个二传手,和延迟加载的依赖性,但我会继续的构造函数是:

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