【发布时间】:2013-01-23 09:00:25
【问题描述】:
编辑 1:似乎我没有很好地解释自己。 Foo 类不是实体。只是一个通用模型,我想访问实体管理器。
编辑 2:我认为我的问题没有答案。基本上,我想要一个可以访问 EntityManager 的类,而无需服务管理器调用这个类,这仅仅是因为它可能被一个也未被服务管理器调用的类调用。换句话说,我试图实现 Zend_Registry 在 ZF1 中实现的目标。我必须找到另一种方法来做我想做的事情。
我正在尝试在模型中访问 Doctrine 的实体管理器,其方式与在控制器中所做的类似:
$this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
ZF2 手册 (http://framework.zend.com/manual/2.0/en/modules/zend.service-manager.quick-start.html) 说:
默认情况下,Zend Framework MVC 注册一个初始化器,它将 ServiceManager 实例(Zend\ServiceManager\ServiceLocatorInterface 的实现)注入到任何实现 Zend\ServiceManager\ServiceLocatorAwareInterface 的类中。
所以我创建了以下类:
<?php
namespace MyModule\Model;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class Foo implements ServiceLocatorAwareInterface
{
protected $services;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->services = $serviceLocator;
}
public function getServiceLocator()
{
return $this->services;
}
public function test()
{
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
}
}
然后,从另一个类中,我这样称呼这个类:
$foo = new \MyModule\Model\Foo();
$foo->test()
这会引发以下错误:
PHP 致命错误:在非对象上调用成员函数 get()
所以,我想我在某个地方遗漏了一些东西,但是什么?在哪里?如何?也许有一个更容易访问的实体管理器?
谢谢!
【问题讨论】:
-
您不应在教义实体中使用实体管理器。 Doctrine 2 实体只是表上操作的数据存储,您可能希望查看可以访问实体管理器的自定义存储库类。如果您提供一个示例,说明您想对实体内部的实体管理器执行什么操作,我可能会帮助您找到执行此操作的正确方法。根据您的问题,仅当您使用服务定位器/DI 来获取您的实体时,它才应该被初始化。
-
我建议您不要在任何类中手动检索 EM,因为这会让您有时间创建单元测试。此外,如果您将来更改服务别名 (doctrine.entitymanager.orm_default),则需要重构所有内容。顺便说一句,您正在使用
new关键字创建实例。如果您使用 ServiceManager 和/或 Di,ZF2 只能注入依赖项。 -
啊,是的,还有单元测试。但是在实体内部拥有实体管理器甚至是最糟糕的设计 Daniel M。它被教义团队阻止,因为它非常违反教义的设计模式。实体只是一个数据存储——不多也不少。关于这个问题的第一个答案:stackoverflow.com/questions/4108291/… 我认为这个问题描述得非常好。
-
谁说过实体中的实体管理器?如果不清楚,问题是关于从通用类访问实体管理器。
-
丹尼尔 M:谢谢。您关于不使用新关键字的评论至少给了我进一步调查的方向。
标签: doctrine-orm zend-framework2