php - zend 框架 2 : how to properly inject factory to controller to get different mapper classes?

标签 php zend-framework2 laminas-api-tools

我正在使用基于 ZF2 构建的 Apigility。将请求分派(dispatch)给 Controller 的操作后,我需要选择合适的适配器来处理请求 - 基于传入的参数。

通常,Controller 由 ControllerFactory 实例化,您可以在其中提供所有依赖项,假设我需要注入(inject)某种映射器类。这很容易,如果我知道,我将在 Controller 中使用哪一个。如果我需要让 Controller 决定使用哪个映射器,这是有问题的。

假设用户正在使用参数 'adapter1' 请求类似 getStatus 的内容,而另一个用户正在访问相同的操作,但使用参数 'adapter2'.

因此,我需要注入(inject) adapter1 映射器或 adapter2 映射器,它们具有相似的接口(interface),但构造函数不同。

处理这种情况的正确方法是什么?

可能的解决方案是提供某种工厂方法,这将提供请求的适配器,但是 - 应避免使用 SM int 模型类。

另一种方法是直接在 Controller 的操作中使用 SM,但这不是最佳方法,因为我不能为另一个操作/ Controller 重用“switch-case”逻辑。

请问如何处理?

最佳答案

您可以为此使用 Controller 插件。

像这样,您可以在需要时在 Controller 中获取适配器,而无需注入(inject) ServiceManager 并且无需将所有逻辑添加到工厂。适配器只会在您在 Controller 操作方法中请求时被实例化。

首先你需要创建你的 Controller 插件类(扩展 Zend\Mvc\Controller\Plugin\AbstractPlugin):

<?php
namespace Application\Controller\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class AdapterPlugin extends AbstractPlugin{

    protected $adapterProviderService;

    public function __constuct(AdapterProviderService $adapterProviderService){
        $this->adapterProviderService = $adapterProviderService;
    }

    public function getAdapter($param){
        // get the adapter using the param passed from controller

    }
}

然后一个工厂将你的服务注入(inject)到类中:

<?php
namespace Application\Controller\Plugin\Factory;

use Application\Controller\Plugin\AdapterPlugin;

class AdapterPluginFactory implements FactoryInterface
{
    /**
     * @param  ServiceLocatorInterface $serviceController
     * @return AdapterPlugin
     */
    public function createService(ServiceLocatorInterface $serviceController)
    {
        $serviceManager = $serviceController->getServiceLocator();
        $adapterProvicerService = $serviceManager>get('Application\Service\AdapterProviderService');
        return new AdapterPlugin($adapterProviderService);
    }
}

然后你需要在你的 module.config.php 中注册你的插件:

<?php
return array(
    //...
    'controller_plugins' => array(
        'factories' => array(
            'AdapterPlugin' => 'Application\Controller\Plugin\Factory\AdapterPluginFactory',
        )
    ),
    // ...
);

现在您可以像这样在 Controller 操作中使用它:

protected function controllerAction(){
    $plugin = $this->plugin('AdapterPlugin');
    // Get the param for getting the correct adapter
    $param = $this->getParamForAdapter();
    // now you can get the adapter using the plugin
    $plugin->getAdapter($param);
}

阅读更多关于 Controller 插件的信息 here in the documentation

关于php - zend 框架 2 : how to properly inject factory to controller to get different mapper classes?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37051761/

相关文章:

php - 将数据添加到$_POST并提交到另一个页面

php - 如何从另一个变量名创建变量?

namespaces - 如何将 LESS 集成到 ZendFramework 2

php - 在映射器中注入(inject)数据库适配器

php - mysql_field_type 区分varchar和text

PHP 兄弟类继承

php - ZF2 日期之间

php - 如何将带下划线的表列映射到 ZF2 中的驼峰式模型类属性?

php - 在私有(private)函数的数组上插入元素

php - Zend 2 条件验证器