This is achieved via accessible properties. For example, using public properties...
class Stuff {
public function foo() {}
}
class Bar {
/**
* @var Stuff
*/
public $stuff;
public function ___construct(Stuff $stuff) {
$this->stuff = $stuff;
}
}
class Controller {
/**
* @var Bar
*/
public $bar;
public function __construct(Bar $bar) {
$this->bar = $bar;
}
}
$stuff = new Stuff();
$bar = new Bar($stuff);
$controller = new Controller($bar);
$controller->bar->stuff->foo();
I wouldn't recommend this as it leaves your classes open to external modification. Another method might be via magic getter methods, for example
class Controller {
private $properties = [];
public function __construct(Bar $bar) {
$this->properties['bar'] = $bar;
}
public function __get($name) {
return array_key_exists($name, $this->properties)
? $this->properties[$name] : null;
}
}
This means you can still access the property in the private $properties array like it was a public property (eg $controller->bar) without it being open to external modification.
In my opinion though, keep properties private / protected and provide accessor methods
class Controller {
/**
* @var Bar
*/
private $bar;
public function __construct(Bar $bar) {
$this->bar = $bar;
}
/**
* @return Bar
*/
public function getBar() { return $this->bar; }
}
$controller->getBar()->someBarMethod()->etc();
$controllerhas a propertybar; whatever is in it has a propertystuff; whatever is in there has a methodfoo; and this method will be invoked.