PHP OOP: What am I doing wrong?
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:
$c->config = function ($c) { return new Config(); };
Your original code was
$config = $c->config = function ($c) { return new Config(); };
I'm guessing this threw an exception on $config->setting = 'a value'
. $config
and $c->config
were both defined as a Closure that would return a new Config
object. Since $config
was a Closure, it would never have a setting
property.
Your updated code is
$c->config = function ($c) { return new Config(); }; // $c->config is a closure as described
$config = $c->config; // $config is a new Config object
Now $config
is being defined as a Config
class, not a Closure, so $configure->setting
is valid.
However, $c->config
still refers to a Closure returning a new Config
object. Since this new Config
object 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:
$c->MockObject = function ($c) { return new MockObject($config); };
精彩评论