我正在zend-framework2建立一个模块。我想在Controller类的构造函数中访问ServiceLocator
。
public function __construct() {
var_dump($this->getServiceLocator()->get('Config'));
}
但它会出现以下错误。
在非对象上调用成员函数get()
当我试图在行动中得到它时,它完美无缺 -
public function inAction() {
$sm = $this->getServiceLocator();
$config = $sm->get('Config');
}
在构造函数中获取ServiceLocator
的正确方法是什么?
答案 0 :(得分:5)
在构建类时,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;
最简单的解决方法是在控制器内写一个懒惰的getter函数:
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()
内可用,以防您想要删除整个配置的特定部分。