在控制器类的构造函数中获取ServiceLocator


Get ServiceLocator in Constructor of Controller Class

我正在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的正确方法是什么?

在构造类时,尚未注入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。这最多在Module类的getControllerConfig()函数中完成

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

然后,配置将被注入到您的控制器中,它也将在__construct()中可用,以防您想要删除整个配置的特定部分。