问题 Zend Framework - Doctrine 2集成:存储EntityManager的位置?


我正在整合Zend Framework和Doctrine 2。

问题是,在我的控制器和视图中,需要访问模型。我可以通过一个完成所有这些 EntityManager的单个实例

我在哪里存储这个实例?

  • Zend_Registry ?这就是它现在的位置,它可以从任何地方访问,但不是很实用: $em = Zend_Registry::get('EntityManager');
  • 作为控制器和查看属性?这将是可访问的 $this->em, 我喜欢这个
  • 创建一个将返回实例的工厂类? $em = My\EntityManager\Factory::getInstance();。封装很好,但输入时间很长......
  • 是个 EntityManager 单身人士已经? - >(更新)不是不是

10213
2018-04-29 17:51


起源

实体经理不是单身人士。可以使用多个实体管理器来处理同一请求中的不同数据库。 - rojoca
好的,谢谢你的信息,问题更新 - Matthieu Napoli


答案:


我不建议直接在您的控制器和视图中使用EntityManager。相反,使用服务层并注入EntityManager。

我有两个自定义操作助手,一个用于检索存储库,另一个用于服务。每个操作都包含对EntityManager的引用,并在将其交还给Controller之前将其注入。

不是我的实际代码,而是类似的东西(未经测试):

我的/控制器/动作/助手/ Service.php

<?php

namespace My\Controller\Action\Helper;

use Doctrine\ORM\EntityManager;

class Service extends \Zend_Controller_Action_Helper_Abstract
{

    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function direct($serviceClass)
    {
        return new $serviceClass($this->em);
    }

}

您可以编写类似的Action Helper来检索存储库。

然后,在您的引导程序中注册帮助程序(我们也可以访问EntityManager):

<?php

use Zend_Controller_Action_HelperBroker as HelperBroker,
    My\Controller\Action\Helper\Service;

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

    public function _initActionHelpers()
    {
        $this->bootstrap('doctrine');
        $em = $this->getResource('doctrine');

        HelperBroker::addHelper(new Service($em));
    }

}

现在写一个简单的服务。

我/域/博客/服务/ PostService.php

<?php

namespace My\Domain\Blog\Service;

use Doctrine\ORM\EntityManager,
    My\Domain\Blog\Entity\Post;

class PostService implements \My\Domain\Service
{

    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function createPost($data)
    {
        $post = new Post();
        $post->setTitle($data['title']);
        $post->setContent($data['content']);

        $this->em->persist($post);
        $this->em->flush(); // flush now so we can get Post ID

        return $post;
    }

}

并在控制器动作中将它们组合在一起:

<?php

class Blog_PostController extends Zend_Controller_Action
{

    private $postService;

    public function init()
    {
        $this->postService = $this->_helper->Service('My\Domain\Blog\PostService');
    }

    public function createPostAction()
    {
        // normally we'd get data from the actual request
        $data = array(
            "title" => "StackOverflow is great!",
            "content" => "Imagine where I'd be without SO :)"
        );
        // and then validate it too!!

        $post = $this->postService->createPost($data);
        echo $post->getId(); // Blog post should be persisted
    }

}

12
2018-05-03 13:01



在上面的Service动作帮助器中,您将要扩展Zend_Controller_Action_Helper_Abstract,而不是Zend_View_Helper_Abstract。 - Jeremy Hicks


自从 EntityManager 通常在引导期间创建和配置 - 作为显式的返回值 _initDoctrine() 调用或使用应用程序资源 - 将其存储在 Bootstrap 似乎对我来说最有意义。然后在控制器内部,它可以访问:

$em = $this->getInvokeArg('bootstrap')->getResource('doctrine');

我看到很多通过前端控制器单例访问bootstrap的例子:

$em = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('doctrine');

它具有无处不在的优势。


4
2018-04-30 02:33



这是最好的选择,你应该尽可能避免使用Zend_Registry。虽然我不建议在任何Zend Framework组件中使用; EntityManager只能由服务和存储库使用。 - Cobby
@Cobby:什么是“服务和存储库”?谢谢 - Matthieu Napoli
@大卫 $em = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('doctrine'); 打字很长!它会变得非常无聊;) - Matthieu Napoli
@Matthieu退房 这篇博文 和 学说参考指南 和 这个问题。 - Cobby
@Matthieu确实很长。太久了。就像在@ Cobby的第二个链接中一样,我可能只在控制器中使用它一次 init() 方法或动作助手。 - David Weinraub


看看Bisna软件包提供的集成,由一个Doctrine 2贡献之一编写。它是在 https://github.com/guilhermeblanco/ZendFramework1-Doctrine2

它允许您在您的配置中配置Doctrine 的application.ini。它使用应用程序资源插件来处理ini设置。我为Bisna写了文档。在您阅读本文时,它可能会集成到包中。如果没有,你可以找到它 https://github.com/kkruecke/ZendFramework1-Doctrine2, 在里面 bisna的文档/ HTML 该包的子目录。我还把文档放了 http://www.kurttest.com/zfa/bisna.html (虽然这可能是暂时的)。


1
2018-06-07 00:11





我将实体管理器存储在Zend_Registry中,然后我还创建了一个动作助手,我在控制器中调用它。


0
2018-04-30 04:35





我认为Zend_Registry是一种商品创意。

基本上从视图访问EM是个坏主意,如果你真的需要这个功能,你可以创建一个视图助手,并使用它


-2
2018-04-29 22:01



从视图或通过Zend_Registry访问EM是一个坏主意。该视图不应直接处理EM - Zend_Registry是一个坏主意,因为它并不比全局变量更好;但是,它可以以非全局静态的方式使用,但这不是我们在这里谈论的:) - Wil Moore III
我没有说这是从视图中直接使用Zend_Registry的好方法,也是关于EM的好方法。我说过,观点需要助手 - azat