ZF2和实体管理器(Doctrine)

7

我有一个问题。我试图在没有控制器的情况下获取实体管理器,但我找不到方法。 此时,我通过以下方式获取实体管理器:

(Controller)
public function getEntityManager()
{
    if (null === $this->_em) {
        $this->_em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
    }
    return $this->_em;
}

(Plugin)
public function getEntityManager()
{
    if($this->_em == null){
        $this->_em = $this->getController()->getServiceLocator()->get('doctrine.entitymanager.orm_default');
    }
    return $this->_em;
}

您好,我需要一个控制器。但是,如果我在模型中需要EntityManager,我会遇到问题。我可以将控制器传递给模型,但我认为这是一种非常糟糕的方式。

您有没有想过如何在没有控制器的情况下获取EntityManager?

2个回答

8
我处理Doctrine的方式是通过服务,我像下面这样做:

我通过服务来处理Doctrine,做法如下:

//some Controller
public function someAction()
{
    $service = $this->getServiceLocator()->get('my_entity_service');
    return new ViewModel(array(
        'entities' => $service->findAll()
    ));
}

Service->findAll()的样子如下:

public function findAll()
{
    return $this->getEntityRepository()->findAll();
}

现在我们需要定义my_entity_service。我将在我的Module.php中完成此操作。
public function getServiceConfig()
{
    return array(
        'factories' => array(
            'my_entity_service' => 'Namespace\Factory\MyServiceFactory'
        )
    );
}

接下来我创建工厂(注意:这也可以通过在Module.php内使用匿名函数来完成)

<?php
namespace Namespace\Factory;

use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
use Namespace\Model\MyModel;

class MyServiceFactory implements FactoryInterface
{
    /**
     * Create service
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @return mixed
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $myModel= new MyModel();
        $myModel->setEntityManager($serviceLocator->get('Doctrine\ORM\EntityManager'));

        return $myModel;
    }    
}

现在这里的内容可能有些费解:D,但实际上所发生的事情非常简单。您不必创建模型然后以某种方式到达EntityManager,而是调用ZF2的ServiceManager为您创建模型,并将EntityManager注入其中。如果您仍然感到困惑,我很乐意尝试更好地解释自己。但为了进一步澄清,我想知道您的用例,即:您需要EntityManager的原因或您确切需要它的位置。此外,以下代码示例超出了问题范围。只是为了给您提供一个通过ServiceFactories与表单进行交互的实时示例。
public function createService(ServiceLocatorInterface $serviceLocator)
{
    $form = new ReferenzwertForm();
    $form->setHydrator(new DoctrineEntity($serviceLocator->get('Doctrine\ORM\EntityManager')))
         ->setObject(new Referenzwert())
         ->setInputFilter(new ReferenzwertFilter())
         ->setAttribute('method', 'post');

    return $form;
}

4
您的真正问题是“如何在自己的类中获取ServiceManager实例”。
请查看文档:(页面底部http://zf2.readthedocs.org/en/latest/modules/zend.service-manager.quick-start.html
默认情况下,Zend Framework MVC注册了一个初始化程序,该程序将向实现Zend\ServiceManager\ServiceLocatorAwareInterface接口的任何类注入ServiceManager实例,该实例是Zend\ServiceManager\ServiceLocatorInterface的实现。一个简单的实现看起来像下面这样。
因此,在您的类中实现ServiceLocatorInterface,然后在您的类内部可以调用:
$this->getServiceLocator()->get('doctrine.entitymanager.orm_default');

或任何您已注册的服务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接