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


How to get an Instance of ServiceManager into a Model in ZF2

好的,所以我将ZF2与Doctrine的ORM模块一起使用

我有一个模型叫ProjectGateway.php

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

模型是否需要扩展类? 我是否缺少一些进口?

我能够通过控制器访问它。

任何朝着正确方向的方向引导将不胜感激。

有两种方法可以做到这一点:

  1. 将模型添加为ServiceManager配置中的服务,并确保模型类实现Zend'Service'ServiceLocatorAwareInterface类。
  2. getter/setter通过另一个使用该ServiceManager的类手动将服务管理器添加到模型中,例如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类中使用服务管理器:

public function someMethodInProjectGateway()
{
    $serviceManager = $this->getServiceLocator();
}
更新 04/

06/2014: 方法 2:

基本上,模型中需要的是ServiceManager的吸气剂/设置器,如方法 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 多得多,因为在第一次调用模型之前不会实例化该模型。