2013-11-21 5 views
1

Я строю модуль в . Я хочу получить доступ к ServiceLocator в конструкторе класса Controller.Получить ServiceLocator в конструкторе контроллера класса

public function __construct() { 
    var_dump($this->getServiceLocator()->get('Config')); 
} 

Но он дает следующую ошибку.

Call to a member function get() on a non-object

Когда я попытался получить это в действии, он отлично работает -

public function inAction() { 
    $sm = $this->getServiceLocator(); 
    $config = $sm->get('Config'); 
} 

Что такое правильный способ получить ServiceLocator в конструкторе?

ответ

4

Во время построения класса зависимость ServiceLocator еще не введена. Это происходит после этого через инициализаторы.

Последовательность действий так:

- controller called "My\Controller\FooController" 
- resolve string to classname 
- $ctrl = new FooController(); // This is where __construct() is called 
if $ctrl instanceof AbstractActionController 
    $ctrl->setServiceLocator($serviceLocator); 
endif 
- return $ctrl; 

Самый простой обходной путь, чтобы написать себе ленивым функцию геттер внутри контроллера:

protected $config; 

public function getConfig() { 
    if (null === $this->config) { 
     $this->config = $this->getServiceLocator()->get('config'); 
    } 
    return $this->config; 
} 

Этот подход будет работать, и вы будете счастливы. Однако вы должны знать, что на самом деле это не лучшая практика, поскольку вы называете зависимость от другой зависимости. Лучше всего было бы на самом деле ввести конфигурацию в ваш контроллер.

public function __construct(array $config) { 
    $this->config = $config; 
} 

И вместо invokable вы пишете factory. Это делается в лучшем случае в getControllerConfig() функции вашего Module -класса

public function getControllerConfig() { 
    return array(
     'factories' => array(
      'My\Controller\FooController' => function($cpm) { 
       $sl = $cpm->getServiceLocator(); 
       return new FooController(
        $sl->get('config') 
       ); 
      } 
     ) 
    ); 
} 

И тогда конфиг будет введен в контроллер, и он также будет доступен в вашем __construct() в случае, если вы хотите вырезать определенные части целая конфигурация.

+0

Спасибо @Sam за такой приятный ответ. Я попробовал второе решение, но я получил следующую ошибку. * Допустимая фатальная ошибка: аргумент 1 передан Auth \ Controller \ AuthController :: __ construct() должен быть из массива типов, не задан, ... * –

+0

@AshwiniAgarwal Попробуйте var_dump ($ sl-> get ('config «)); и посмотреть, вернет ли он что-то (сделать это за пределами нового вызова FooController()) и сначала сохранить его в переменной - этот код должен работать - удалил ли ваш contrller-псевдоним из массива invokables? – Sam

+0

@Sam .. Нужно ли мне делать некоторые другие обновления конфигурации, потому что там ничего не печатают. * (Я попытался поставить 'echo 'test';' непосредственно перед 'new FooController()', и он ничего не печатает.) * –

Смежные вопросы