如何在 ZF2 中将 ServiceManager 的实例放入模型中

Posted

技术标签:

【中文标题】如何在 ZF2 中将 ServiceManager 的实例放入模型中【英文标题】:How to get an Instance of ServiceManager into a Model in ZF2 【发布时间】:2013-09-23 14:31:58 【问题描述】:

好的,我正在使用 ZF2 和 Doctrine 的 ORM 模块

我有一个模型叫ProjectGateway.php

我的问题是如何通过getServiceLocator()-> 访问服务定位器我收到未定义类错误的调用。

模型是否需要扩展一个类?我错过了一些进口吗?

我可以通过控制器访问它。

我们将不胜感激。

【问题讨论】:

【参考方案1】:

有两种方法:

    将模型作为服务添加到ServiceManager 配置中,并确保模型类实现Zend\Service\ServiceLocatorAwareInterface 类。 通过另一个使用ServiceManager 的类,通过getter/setter 手动将服务管理器添加到模型中,例如。 Controller

方法一:

// module.config.php
<?php
return array(
    'service_manager' => array(
        'invokables' => array(
            'ProjectGateway' => 'Application\Model\ProjectGateway',
        )
    )
);

现在确保您的模型实现了ServiceLocatorAwareInterface 及其方法:

namespace Application\Model;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class ProjectGateway implements ServiceLocatorAwareInterface 

    protected $serviceLocator;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) 
        $this->serviceLocator = $serviceLocator;
    

    public function getServiceLocator() 
        return $this->serviceLocator;
    

您现在可以通过以下方式从控制器获取您的ProjectGateway

$projectGateway = $this->getServiceLocator->get('ProjectGateway');

因此,您现在可以通过执行以下操作在 ProjectGateway 类中使用 ServiceManager:

public function someMethodInProjectGateway()

    $serviceManager = $this->getServiceLocator();

2014 年 4 月 6 日更新: 方法 2:

您的模型中需要的基本上是 ServiceManager 的 getter/setter,如方法 1 所示,如下所示:

namespace Application\Model;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class ProjectGateway implements ServiceLocatorAwareInterface 

    protected $serviceLocator;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) 
        $this->serviceLocator = $serviceLocator;
    

    public function getServiceLocator() 
        return $this->serviceLocator;
    

那么你需要从其他地方(例如Controller)做的就是解析那里的ServiceManager

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Application\Model\ProjectGateway;

class SomeController extends AbstractActionController

    public function someAction()
    
        $model = new ProjectGateway();

        // Now set the ServiceLocator in our model
        $model->setServiceLocator($this->getServiceLocator());
     

仅此而已。

但是,使用方法 2 意味着 ProjectGateway 模型在您的应用程序中并不随需应变。您每次都需要实例化和设置ServiceManager

但是,作为最后一点,必须注意的是,方法 1 的资源并不比方法 2 重很多,因为模型在您第一次调用之前没有实例化。

【讨论】:

好的,谢谢。我已经编辑了您建议的更改,但我现在返回一个错误致命错误:Base\Model\ProjectGateway::setServiceLocator() 的声明必须与 Zend\ServiceManager\ServiceLocatorAwareInterface::setServiceLocator(Zend\ServiceManager\ServiceLocatorInterface $serviceLocator) 兼容在 /Volumes/Data/Sites/cole/module/Base/src/Base/Model/ProjectGateway.php 第 8 行 您可以查看 Zend\ServiceManager\ServiceLocatorAwareInterface 并从那里复制定义。它应该和那个完全一样。我应该测试一下代码,但我只是想不通。 我刚刚看了看好像忘记了一个使用类。您能否将此添加到其他用途:use Zend\ServiceManager\ServiceLocatorInterface;

以上是关于如何在 ZF2 中将 ServiceManager 的实例放入模型中的主要内容,如果未能解决你的问题,请参考以下文章

ZF2如何在where子句中将值作为表达式传递

如何将侦听器代码从闭包移到方法并在ZF2中将参数传递给它?

如何在 zf2 中获取最后插入的 id?

ZF2:如何从其他模块渲染视图

关于ServiceLocator ,AdpaterAwareInterface 注入

如何在 ZF2 中启用显示全局标签取消 FormMultiCheckbox?