This reminds me of baboushka's
Of course you're bound to get infinite recursion here. Both functions call each other, each time returning a new instance, that is passed the return value of the call to their function-counter part, which in turn calls the function again, which calls the other function again, which calls....
Bottom line: when you have 2 classes that depend on each other from the get-go (__construct
), your design is probably flawed.
The way you've defined both constructors, you'll never be able to create an instance of the classes. Simply because you need to instantiate both classes at the same time.
You can't, you simply cannot do that.
Try this:
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;
}
}
By setting the default value of the constructor arguments to null
, passing an instance has become optional, so now you can do this:
$a = new A;
$b = new B($a);
//or even:
$bFromA = $a->b;
BTW: always declare your properties beforehand. It'll speed up your classes.
Personally, I'd use a getter and a setter, and lazy-load the dependency, but I would keep the constructor as is:
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;
}
}
Using Pimple:
$c['aService'] = function($c)
{
return new A;
};
$c['bService'] = function($c)
{
return new B;
};
$b = $c->bService;
$b->getA();//works just fine