Doctrine orm 如何为EntityManager创建通用模型?
我正在尝试使用ZF2和Doctrine 2创建一些东西。但我有点迷失了我想要实现的目标 首先,我现在使用$em=$this->getServiceLocator->get'Doctrine\ORM\EntityManager';在控制器内部,它将工作 但我想要的是更详细的东西,比如:Doctrine orm 如何为EntityManager创建通用模型?,doctrine-orm,zend-framework2,Doctrine Orm,Zend Framework2,我正在尝试使用ZF2和Doctrine 2创建一些东西。但我有点迷失了我想要实现的目标 首先,我现在使用$em=$this->getServiceLocator->get'Doctrine\ORM\EntityManager';在控制器内部,它将工作 但我想要的是更详细的东西,比如: class BaseModel extends Doctrine\ORM\EntityManager { public function save() { $em->persist($this
class BaseModel extends Doctrine\ORM\EntityManager
{
public function save()
{
$em->persist($this);
$em->flush();
}
}
/**
* @ORM\Entity
*/
class Customer extends BaseModel
{
// getters setters
}
class IndexController
{
public function indexAction()
{
$customer = new Customer();
$customer->setName('asd');
$customer->save();
Customer::findAll();
}
}
我已经开始这样做:
namespace Ws\Model;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
class BaseModel implements ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
public function write() {
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
return $em->getRepository(__CLASS__);
}
}
但是没有成功
我知道这不仅仅是一个问题,但它是否有可能在这里帮助我,甚至通过一些链接,可以帮助我在这个旅程
谢谢。您有没有看过Zend\ServiceManager\ServiceLocatorAwaRetrit的实现?它只是给你,但当然,如果你不设定它,你永远不会得到它。所以$this->getServiceLocator将始终返回null
你最好使用依赖注入,不要注入服务定位器,而是注入所需的服务,或者,正如@Cerad所指出的那样,按照设计的方式使用条令。你很幸运。我自己刚刚创建了一个用于我自己的供应商包 虽然您的代码很混乱,但我将假设您引用的模型是实体,而不是实体和存储库的组合 但是,要遵守代码 请特别注意名称空间,并相应地组织文件夹结构和文件名 文件:repoName/src/Entity/AbstractEntity.php
<?php
namespace Company\Core;
use Doctrine\ORM\Mapping as ORM;
use Company\Core\Listener\ServiceLocatorAwareEntity;
/**
* Class AbstractEntity
* @package Company\Core\Entity
*
* @ORM\MappedSuperclass
* @ORM\HasLifecycleCallbacks
*/
abstract class AbstractEntity extends ServiceLocatorAwareEntity
{
/**
* @var int
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
* @return AbstractEntity
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
}
<?php
namespace Company\Core\Listener;
use Zend\Di\ServiceLocator;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ServiceLocatorAwareEntity implements ServiceLocatorAwareInterface
{
protected $sm;
/**
* Set the service locator
*
* @param ServiceLocatorInterface $sm
*
* @return void
*/
public function setServiceLocator(ServiceLocatorInterface $sm)
{
$this->sm = $sm;
}
/**
* Get the service locator
*
* @return ServiceLocator ServiceLocator instance
*/
public function getServiceLocator()
{
return $this->sm;
}
}
由于此设置,请确保将@ORM\HasLifecycleCallbacks原则注释添加到实体类。上面的函数触发ServiceManagerListener的添加,这反过来又触发其余的
现在剩下的就是在您自己的模块中使用它。如果需要,请无休止地重复:
这里我们回到应用程序本身。
确保对每个实体和控制器执行以下操作,您应该会没事
创建以下内容:
<?php
namespace Application\Service;
use Company\Core\Service\AbstractEntityService;
class IndexControllerService extends AbstractEntityService
{
//Yes really, this class is empty. Extends an Abstract class which may not be directly instantiated.
}
'controllers' => [
'factories' => [
IndexController::class => IndexControllerFactory::class,
],
],
'service_manager' => [
'invokables' => [
IndexControllerService::class => IndexControllerService::class,
],
],
好了,应该准备好了 如果您想要一个活动记录实现,那么使用一个基于活动记录的orm,比如propel或Elount。我相信采埃孚有办法将其融入其中。试图使用数据映射器(如信条)将导致无尽的挫折。按照设计的方式使用条令如何?可能会对它的威力感到惊讶。它是目前为止最流行的orm是有原因的。
public function onBootstrap(MvcEvent $e)
{
$sm = $e->getApplication()->getServiceManager();
/** @var EntityManager $em */
$em = $sm->get('doctrine.entitymanager.orm_default');
/** @var \Doctrine\Common\EventManager $dem */
$dem = $em->getEventManager();
/**
* Binds adding EventListener "ServiceManagerListener" to the Doctrine Event PostLoad
*/
$dem->addEventListener([Events::postLoad], new ServiceManagerListener($sm));
}
<?php
namespace Application\Service;
use Company\Core\Service\AbstractEntityService;
class IndexControllerService extends AbstractEntityService
{
//Yes really, this class is empty. Extends an Abstract class which may not be directly instantiated.
}
<?php
namespace Application\Factory;
use Application\Controller\IndexController;
use Application\Service\IndexControllerService;
use Doctrine\ORM\EntityManager;
use Zend\Mvc\Controller\ControllerManager;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceManager;
class IndexControllerFactory implements FactoryInterface
{
/**
* @param ServiceLocatorInterface|ControllerManager $serviceLocator
* @return IndexController
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
/** @var ServiceManager $serviceManager */
$serviceManager = $serviceLocator->getServiceLocator();
/** @var EntityManager $entityManager */
$entityManager = $serviceManager->get('doctrine.entitymanager.orm_default');
/** @var IndexControllerService $entityService */
$entityService = new IndexControllerService($entityManager);
/** @var IndexController $controller */
$controller = new IndexController($entityService);
return $controller;
}
}
<?php
namespace Application\Controller;
use Company\Core\Controller\AbstractActionController;
class IndexController extends AbstractActionController
{
public function indexAction()
{
return [];
}
}
'controllers' => [
'factories' => [
IndexController::class => IndexControllerFactory::class,
],
],
'service_manager' => [
'invokables' => [
IndexControllerService::class => IndexControllerService::class,
],
],