【问题标题】:How to access service locator object inside a controller in ZF3?如何在 ZF3 中访问控制器内的服务定位器对象?
【发布时间】:2017-07-30 06:58:38
【问题描述】:

我正在尝试访问控制器内的服务定位器对象,但无法执行此操作。
我尝试了在线帮助,但他们中的大多数都遵循ZF2的方法

以前zf2 中的 Servicelocator 访问是轻而易举的事,我只需要 $this->getServiceLocator();

我已尝试为我的控制器创建工厂类并在那里创建 createService 方法,但它说我也必须实现 __invoke() 方法。

我的目标是做这样的事情

public function getPropertyTable()
{
    if (!$this->PropertyTable) {
        $sm = $this->getServiceLocator();
        $this->PropertyTable = $sm->get('Application\Model\PropertyTable');
    }
    return $this->PropertyTable;
}


谁能提供一个完整的步骤来实现这一点?

在提出这个问题之前,我已经尝试实现几乎所有与 Servicelocator 相关的答案,所以在将其标记为重复或其他内容之前请帮助我,忽略错别字

【问题讨论】:

  • 在 ZF2 中,已确定在控制器中使用服务定位器是一种非常非常非常糟糕的糟糕做法。不可能/不建议在 ZF3 中再次使用该技巧
  • @Hooli 谢谢,我完全理解并同意你的观点,我知道这就是 ZF3 中服务管理器的整个流程发生变化的原因。但这就是我问这个问题的原因,我不知道如何在控制器内调用我的模型的函数。请把我看作一个正在学习这项技术的新手。我希望你能给我一个例子,我如何在 Controller 中调用模型函数。

标签: php zend-framework2 zend-framework3


【解决方案1】:

感谢大家告诉我我做错了。
关于这个主题的更多研究帮助我解决了我的问题
这是我为解决它所做的工作

  • 为您的控制器创建工厂类
    你必须为你的控制器创建一个工厂类,它将实现 zend 的 FactoryInterface。 在那里你必须打电话
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
     {
           return new ListController($container->get(PropertyInterface::class));
     }
    


    在这里,我正在传递 PropertyInterface refrence,它是由我的另一个名为 Property Table 的表实现的,在该表中,我为模型的所有接口函数提供了主体
    像 searchProperty()

  • 在配置文件 module.config.php 中为您的控制器添加工厂类
    指示配置文件让我们的工厂为我们的控制器创建对象

    'controllers' => [
                'factories' => [
                    // Update the following line:
                    Controller\ListController::class => Factory\ListControllerFactory::class,
                ],
            ],
    


  • 在配置文件中注册您的模型
    您必须为服务管理器添加新部分并在那里提供您的模型类。

    // Add this section:
            'service_manager' => [
                'aliases' => [
                    Model\PropertyInterface::class => Model\PropertyTable::class,
                ],
                'factories' => [
                    Model\PropertyTable::class => InvokableFactory::class,
                ],
            ],
    



  • 现在剩下的就是在 PropertyInterface 中为它们添加函数并在 PropertyTable 中为它们添加实现,然后在控制器中调用它们

    这个 Complete Steps for implementation 帮助我实施了新流程。
    感谢社区。你们都是最好的。

    【讨论】:

    • 很高兴你终于解决了你的问题,如果我的回答帮助你解决了你的问题,顺便提个赞可能会很好......
    【解决方案2】:

    只要ZF3中的新工厂界面是:

    interface FactoryInterface
    {
        /**
         * Create an object
         *
         * @param  ContainerInterface $container
         * @param  string             $requestedName
         * @param  null|array         $options
         * @return object
         */
        public function __invoke(ContainerInterface $container, $requestedName, array $options = null);
    }
    

    你必须像这样实现你的工厂。

    为了帮助你,你可以使用link

    编辑:

    实际上你应该有这个:

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $propertyTable = $container->get('Application\Model\PropertyTable');
        return new Controller($propertyTable);
    }
    

    【讨论】:

    • 感谢您为我指明了正确的方向,我在网上查找了您的答案并遇到了 this link 我从这个链接实现了代码,并且非常成功这里。遵循此代码的唯一问题是现在我无法访问我的 sql 查询的适配器对象。你能帮我吗,在我的 PropertyTable 模型中,如何注入 Zend\Db\Adapter\Adapter 类对象。这样我就可以像这样使用它:$sql = new Sql($this->adapter);
    • @PankajJha 已编辑
    【解决方案3】:

    另一种方式

    /**
     * Retrieve service manager instance
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @return ContainerInterface
     */
    public function getServiceLocator()
    {
        return $this->getEvent()->getApplication()->getServiceManager();
    }
    
    

    【讨论】:

      【解决方案4】:

      在 ZF3 中,不建议将服务定位器传递给控制器​​。 您需要从控制器工厂内的 $container 获取所有依赖项,并通过构造函数(或设置器)将它们传递给控制器​​。

      【讨论】:

      • 你能给我看一个使用setter的例子吗?或任何链接
      • @Athar 只需在此处或谷歌搜索中输入“php 依赖注入设置器”。有很多关于这个主题的文章。
      猜你喜欢
      • 2016-12-09
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多