单工厂适用于多个控制器?

Rob*_*Rob 6 zend-framework2

简而言之我的问题:我可以为多个控制器使用单个工厂吗?

更多细节:

我在/config/autoload/global.php中有一些全局非模块特定设置,如下所示:

return array(
    'settings' => array(
        'setting_a' => 'foo',
        'setting_b' => 'bar'
    ),

    // More ZF default configuration ...
);
Run Code Online (Sandbox Code Playgroud)

现在,我希望在每个控制器中都可以访问这些设置,而无需一直打电话$this->getServiceLocator()->get('config').

所以我的想法是$settings在我的中引入一个类属性,AbstractController其中注入了配置数组.我试图直接在构造函数中获取配置AbstractController.但是getServiceLocator()当时似乎没有准备好并返回NULL.

我可以为每个控制器构建Controller Factories并注入如下设置:

class ControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator) {
        $config = $serviceLocator->get('config');
        return new \MyModule\Controller\MyController($config['settings']);
    }
}
Run Code Online (Sandbox Code Playgroud)

但它会一遍又一遍地相同.所以我的问题是:我可以为多个控制器使用单个工厂吗?

在我的module.config.php中,我可以为多个控制器指定一个工厂类:

return array(
    'controllers' => array(
        'factories' => array(
            'MyModule\Controller\MyControllerA' => 'MyModule\Factory\ControllerFactory',
            'MyModule\Controller\MyControllerB' => 'MyModule\Factory\ControllerFactory',
            'MyModule\Controller\MyControllerC' => 'MyModule\Factory\ControllerFactory',
        )
    ),
);
Run Code Online (Sandbox Code Playgroud)

但是在工厂中我需要手动返回实际的Controller对象(参见上面的例子),当然这只适用于每个Controller一个Factory.

希望,我明白我的问题.

更新2013-03-24:

虽然我首先通过创建初始化程序来遵循建议的解决方案,但我从未真正喜欢仅用于注入配置.

所以我一直在挖掘并最终创建一个Controller插件来接收设置.

该插件的代码如下所示:

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class Settings extends AbstractPlugin
{
    protected $settings;

    public function __invoke()
    {
        $config = $this->getController()->getServiceLocator()->get('Config');

        if (isset($config['settings']) && is_array($config['settings'])) {
            $this->settings = $config['settings'];
        }

        return $this->settings;
    }
}
Run Code Online (Sandbox Code Playgroud)

添加插件中后module.config.php

'controller_plugins' => array(
    'invokables' => array(
        'settings' => 'My\Controller\Plugin\Settings',
    )
),
Run Code Online (Sandbox Code Playgroud)

我可以通过简单地调用轻松访问控制器中的设置$this->settings().希望这有助于任何人.

DrB*_*eza 6

作为创建控制器实例对已知检查初始化你可以尝试连接的初始化,然后.如果实例匹配给定的接口或抽象类,那么您可以应用一些通用逻辑.

我没有测试与控制器的这种做法,但考虑到ControllerLoader是一种在理论工作的ServiceManager /服务定位它应该的.

'controllers' => array (
    'initializers' => array(
        'MyApplication\Controller\Initializer'
    )
),
Run Code Online (Sandbox Code Playgroud)

然后Initalizer看起来像:

class Initializer implements InitializerInterface
{
    public function initialize($instance, ServiceLocatorInterface $serviceLocator)
    {
        if (!$instance instanceof MyControllerInterface)
        {
            return;
        }

        // Do something for this instance
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 首先尝试在$ serviceLocator上启用var_dump(启用xdebug)应该会给你提示你在那一点上可以提取的内容.还可以尝试$ serviceLocator-> getServiceLocator() - > get('Config'),因为它可能是插件ServiceManager而不是主插件. (2认同)