Zend Framework - интеграция Doctrine 2: где хранить EntityManager?

Я интегрирую Zend Framework и Doctrine 2.

Вопрос в том, что в моих контроллерах и представлениях требуется доступ к модели. Я могу сделать все это через один экземпляр EntityManager.

Где хранить этот экземпляр?

  • Zend_Registry? То, где оно сейчас, доступно извне, но не очень практично: $em = Zend_Registry::get('EntityManager');
  • Как свойство контроллера и вида? Это было бы доступно как $this->em, мне это нравится
  • Создайте класс factory, который вернет экземпляр? $em = My\EntityManager\Factory::getInstance();. Инкапсуляция хороша, но долго печатается...
  • Уже есть EntityManager a Singleton? → (обновление), а не

Ответ 1

Я бы не рекомендовал использовать EntityManager непосредственно в ваших контроллерах и представлениях. Вместо этого используйте сервисный уровень и добавьте EntityManager.

У меня есть два специальных помощника действий, один для извлечения репозиториев и один для служб. Каждое действие содержит ссылку на EntityManager и вводит его, прежде чем передавать его обратно контроллеру.

Не мой фактический код, но что-то вроде этого (не проверено):

My/Controller/Action/Helper/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);
    }

}

Вы можете написать аналогичный помощник действий для извлечения репозиториев.

Затем зарегистрируйте помощника в вашей начальной загрузке (где у нас также есть доступ к 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
    }

}

Ответ 2

Так как EntityManager обычно создается и настраивается во время начальной загрузки - либо в качестве возвращаемого значения явного вызова _initDoctrine(), либо с использованием ресурса приложения - сохранение его в Bootstrap, кажется, имеет для меня наибольший смысл, Затем внутри контроллера он доступен как:

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

Я вижу много примеров доступа к бутстрапу через синглтон переднего контроллера:

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

который имеет то преимущество, что работает везде.

Ответ 3

Взгляните на интеграцию, предоставляемую пакетом Bisna, написанную одной из доктрин 2. Он находится на https://github.com/guilhermeblanco/ZendFramework1-Doctrine2

Он позволяет вам настроить Doctrine в приложении application.ini. Он использует плагин ресурса приложения для обработки настроек ini. Я написал документацию для Бисны. К тому моменту, когда вы это прочитаете, он может быть интегрирован в пакет. Если нет, вы можете найти его в https://github.com/kkruecke/ZendFramework1-Doctrine2 в подкаталоге bisna-documentation/html этого пакета. Я также разместил документацию http://www.kurttest.com/zfa/bisna.html (хотя это может быть временным).

Ответ 4

Я сохраняю Менеджер сущностей в Zend_Registry, а затем создаю помощник действий, который я вызываю в своих контроллерах.

Ответ 5

Zend_Registry, я думаю, это идея товара.

В принципе, это плохая идея получить доступ к EM из представления, если вам действительно нужна эта функция, вы можете создать помощник вида и использовать его