在Controller类的构造函数中获取ServiceLocator

时间:2013-11-21 06:42:49

标签: php 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的正确方法是什么?

1 个答案:

答案 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()内可用,以防您想要删除整个配置的特定部分。