Symfony,访问getManager()到控制器

时间:2014-03-31 15:42:45

标签: symfony

所以,现在,我在我的控制器的每个动作中得到我的经理:

$em = $this->getDoctrine()->getManager();

有没有更好的方法呢?使用__construct和attribut $ em?不知道吗?我想减少代码的大小..谢谢!

3 个答案:

答案 0 :(得分:1)

您可以重载子类中的setContainer方法并将管理器设置为类属性:

class MyController extends Controller
{
    protected $manager;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->manager = $container->getDoctrine()->getManager();
    }
}

当然,如果您发现自己在很多方法中使用管理器,也许是时候将所有逻辑放入服务并使用适当的依赖注入。

答案 1 :(得分:1)

一种方法:

创建私有方法:

private function manager()
{
    return $this->getDoctrine()->getManager();
}

然后,在你的行动中:

$em = $this->manager();

或直接:

$this->manager()->persist();

答案 2 :(得分:1)

如果您真的想让控制器更精简,也可以编写模型管理器。但这不是新的,不是我的想法。您可以在互联网上找到一些相同的解决方案。

让我们打电话给我们的实体"评论"和Controller" CommentController"。

1)我们的ModelMananger是针对以下界面实现的:

<?php

namespace Sg\ExampleBundle\Doctrine\ModelManager;

interface ModelManagerInterface
{
    /**
     * Creates an empty object instance.
     *
     * @return object
     */
    function create();

    /**
     * Saves an object.
     *
     * @param object  $object   An object instance
     * @param boolean $andFlush Whether to flush the changes (default true)
     *
     * @return void
     */
    function save($object, $andFlush = true);

    /**
     * Removes an object.
     *
     * @param object  $object   An object instance
     * @param boolean $andFlush Whether to flush the changes (default true)
     *
     * @return void
     */
    function remove($object, $andFlush = true);

    /**
     * Finds many objects by the given criteria.
     *
     * @param array $criteria
     *
     * @return array
     */
    function findBy(array $criteria = array());

    /**
     * Finds one object by the given criteria.
     *
     * @param array $criteria
     *
     * @return object|null
     */
    function findOneBy(array $criteria = array());

    /**
     * Finds an object by its primary key / identifier.
     *
     * @param mixed $id The identifier
     *
     * @return object
     */
    function find($id);

    /**
     * Write all changes to the database.
     *
     * @return void
     */
    function flushAllChanges();

    /**
     * Returns the objects's fully qualified class name.
     *
     * @return string
     */
    function getClass();
}

2)现在我使用抽象类来实现常用函数:

<?php

namespace Sg\ExampleBundle\Doctrine\ModelManager;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;

abstract class AbstractModelManager implements ModelManagerInterface
{
    /**
     * The fully qualified class name.
     *
     * @var string
     */
    protected $class;

    /**
     * @var EntityManager
     */
    protected $em;

    /**
     * @var EntityRepository
     */
    protected $repository;


    //-------------------------------------------------
    // Ctor.
    //-------------------------------------------------

    /**
     * Ctor.
     *
     * @param EntityManager $em    An EntityManager instance
     * @param string        $class The class name
     */
    public function __construct(EntityManager $em, $class)
    {
        $this->em = $em;
        $this->repository = $em->getRepository($class);

        $metadata = $em->getClassMetadata($class);
        $this->class = $metadata->getName();
    }


    //-------------------------------------------------
    // ModelManagerInterface
    //-------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public function create()
    {
        $class = $this->class;
        $object = new $class();

        return $object;
    }

    /**
     * {@inheritDoc}
     */
    public function save($object, $andFlush = true)
    {
        $this->em->persist($object);

        if (true === $andFlush) {
            $this->flushAllChanges();
        }
    }

    /**
     * {@inheritDoc}
     */
    public function remove($object, $andFlush = true)
    {
        $this->em->remove($object);

        if (true === $andFlush) {
            $this->flushAllChanges();
        }
    }

    /**
     * {@inheritDoc}
     */
    public function findBy(array $criteria = array())
    {
        return $this->repository->findBy($criteria);
    }

    /**
     * {@inheritDoc}
     */
    public function findOneBy(array $criteria = array())
    {
        return $this->repository->findOneBy($criteria);
    }

    /**
     * {@inheritDoc}
     */
    public function find($id)
    {
        return $this->repository->find($id);
    }

    /**
     * {@inheritDoc}
     */
    public function flushAllChanges()
    {
        $this->em->flush();
    }

    /**
     * {@inheritDoc}
     */
    public function getClass()
    {
        return $this->class;
    }
}

3)CommentModelManager中有特殊功能:

<?php

namespace Sg\ExampleBundle\Doctrine\ModelManager;

use Sg\ExampleBundle\Doctrine\ModelManager\AbstractModelManager as BaseModelManager;
use Sg\ExampleBundle\Entity\User;

class CommentModelManager extends BaseModelManager
{
    /**
     * Find all Comments by given User.
     *
     * @param User $user
     *
     * @return mixed
     */
    public function findCommentsByUser(User $user)
    {
        $qb = $this->repository->createQueryBuilder('c');
        $qb->where('c.createdBy = :user');
        $qb->setParameter('user', $user);

        return $qb->getQuery()->execute();
    }
} 

4)在services.yml中注册CommentModelManager:

services:

# ModelManager

sg_example.doctrine.model_manager.comment:
    class: Sg\ExampleBundle\Doctrine\ModelManager\CommentModelManager
    arguments: [@doctrine.orm.entity_manager, 'Sg\ExampleBundle\Entity\Comment']
# ... 

5)在CommentModel中使用CommentModelManager,如:

<?php

namespace Sg\ExampleBundle\Controller;

use Sg\ExampleBundle\Entity\Comment;

// ...

class CommentController extends Controller
{
    // ..

    public function indexAction()
    {
        $userComments = $this->getCommentModelManager()->findCommentsByUser($this->getUser());

        return array(
            'entities' => $userComments 
        );
    }

    /**
     * Shortcut to return the Comment Model Manager service.
     * 
     * @return \Sg\ChiliManBundle\Doctrine\ModelManager\ChiliModelManager
     */
    protected function getCommentModelManager()
    {
        return $this->container->get('sg_example.doctrine.model_manager.comment');
    }
}