I have a real hard time understanding why the below code doesn’t work as intended. I’ve usually use the bucket dependency injector, but to simplify, I’ve used twittee below, with the very same result.
So why aren’t my modified Config-object (and the created setting-element) available to the MockObject-class? From what I can tell, it’s being passed correctly.
Code:
$c = new Container();
$c->config = function ($c) { return new Config(); };
$config = $c->config;
$config->setting = 'a value';
$c->MockObject = function ($c) { return new MockObject($c->config); };
$c->MockObject; // Error thrown: `Notice: Undefined index: setting`
Classes:
class Container {
protected $s=array();
function __set($k, $c) { $this->s[$k]=$c; }
function __get($k) { return $this->s[$k]($this); }
}
class Config {
public $values = array();
function __set($key, $value){ $this->values[$key] = $value; }
function __get($key) { return $this->values[$key]; }
}
class MockObject {
function __construct(Config $config) { echo $config->setting; }
}
Dependency injection container courtesy of Fabien Potencier; https://github.com/fabpot/twittee
I’m not extremely familiar with DI on PHP, but I think your problem is in this line:
Your original code was
I’m guessing this threw an exception on
$config->setting = 'a value'.$configand$c->configwere both defined as a Closure that would return a newConfigobject. Since$configwas a Closure, it would never have asettingproperty.Your updated code is
Now
$configis being defined as aConfigclass, not a Closure, so$configure->settingis valid.However,
$c->configstill refers to a Closure returning a newConfigobject. Since this newConfigobject doesn’t have a property named “Setting” it’s throwing an error when you try to retrieve it.I’m not sure how it fits with the rest of your design, but the following should work as expected: