我正在整合Zend Framework和Doctrine 2。
问题是,在我的控制器和视图中,需要访问模型。我可以通过 EntityManager的单个实例来完成所有这些。
我在哪里存储此实例?
Zend_Registry
?现在就是这样,它可以从任何地方访问,但不是很实用:$em = Zend_Registry::get('EntityManager');
$this->em
访问,我喜欢这个$em = My\EntityManager\Factory::getInstance();
。封装很好,但很难打字... EntityManager
是单身人士吗? - > (更新)不是答案 0 :(得分:12)
我不建议您直接在控制器和视图中使用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
}
}
答案 1 :(得分:4)
由于EntityManager
通常在引导期间创建和配置 - 作为显式_initDoctrine()
调用的返回值或使用应用程序资源 - 将其存储在Bootstrap
似乎对我来说最有意义。然后在控制器内部,它可以访问:
$em = $this->getInvokeArg('bootstrap')->getResource('doctrine');
我看到很多通过前端控制器单例访问bootstrap的例子:
$em = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('doctrine');
具有无处不在的优势。
答案 2 :(得分:1)
看一下Bisna软件包提供的集成,由一个Doctrine 2贡献之一编写。它位于https://github.com/guilhermeblanco/ZendFramework1-Doctrine2
它允许您在 application.ini 中配置Doctrine。它使用应用程序资源插件来处理ini设置。我为Bisna写了文档。在您阅读本文时,它可能会集成到包中。如果没有,您可以在https://github.com/kkruecke/ZendFramework1-Doctrine2,在该软件包的 bisna-documentation / html 子目录中找到它。我还将文档设为http://www.kurttest.com/zfa/bisna.html(尽管这可能是暂时的)。
答案 3 :(得分:0)
我将实体管理器存储在Zend_Registry中,然后我还创建了一个动作助手,我在控制器中调用它。
答案 4 :(得分:-2)
Zend_Registry我认为这是一个商品创意。
从视图中访问EM基本上是一个坏主意,如果你真的需要这个功能,你可以创建一个视图助手,并使用它