简体   繁体   中英

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); };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM