PHP ООП: Что я делаю не так? - PullRequest
0 голосов
/ 25 августа 2011

Мне очень трудно понять, почему приведенный ниже код работает не так, как задумано. Я обычно использую инжектор зависимостей bucket , но для упрощения я использовал twittee ниже, с тем же результатом.

Так почему же мой модифицированный Config -объект (и созданный установочный элемент) недоступны для MockObject -класса? Из того, что я могу сказать, это передается правильно.

Код:

$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`

Классы:

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

Зависимость инъекционного контейнера любезно предоставлена ​​Fabien Potencier; https://github.com/fabpot/twittee

1 Ответ

0 голосов
/ 25 августа 2011

Я не очень хорошо знаком с DI на PHP, но я думаю, что ваша проблема в этой строке:

$c->config = function ($c) { return new Config(); };

Ваш оригинальный код был

$config = $c->config = function ($c) { return new Config(); };

Полагаю, это исключение на $config->setting = 'a value'. $config и $c->config оба были определены как Замыкание, которое возвратило бы новый объект Config. Поскольку $config был Замкнутым, у него никогда не было бы свойства setting.

Ваш обновленный код

$c->config = function ($c) { return new Config(); };  // $c->config is a closure as described
$config = $c->config;  // $config is a new Config object

Теперь $config определяется как класс Config, а не как Замыкание, поэтому $configure->setting допустим. Тем не менее, $c->config все еще ссылается на Closure, возвращающий новый Config объект. Поскольку этот новый Config объект не имеет свойства с именем «Setting», он выдает ошибку, когда вы пытаетесь получить его.

Я не уверен, как он вписывается в остальную часть вашего дизайна, но следующее должно работать, как и ожидалось:

$c->MockObject = function ($c) { return new MockObject($config); };
...