2

我有一个控制器,它具有在数据库中插入、更新、删除和其他一些操作,但几乎所有操作都包含以下行:

$em = $this->getDoctrine()->getEntityManager(); 
$friend = $em->getRepository('EMMyFriendsBundle:Friend')->find($id);
$user = $this->get('security.context')->getToken()->getUser();

这可以吗,还是代码重复?我试图创建一个名为的属性$em并拥有一个像这样的构造函数:

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

但它没有用。至于查询,尤其是带有$id参数的查询,我什至不知道如何将它们分隔在一个地方,以便每个操作都能够使用它们。一种方法是函数,但是这样的函数有意义吗?如果是,它应该返回什么?数组?

请告诉我最佳方法!

4

4 回答 4

3

What I do, for Symfony2, in the controllers to avoid code duplication is creating a class called Controller.php in which I put the function I often use.

For example :

<?php

namespace YourProject\Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller as BaseController;

/**
 * Base Controller for xxBundle
 */
class Controller extends BaseController
{
    /**
     * Get repository
     *
     * @param string $class class
     *
     * @return Doctrine\ORM\EntityRepository
     */
    protected function getRepository($class)
    {
        return $this->getDoctrine()->getEntityManager()->getRepository($class);
    }

    /**
     * Set flash
     *
     * @param string $type type
     * @param string $text text
     */
    protected function setFlash($type, $text)
    {
        $this->get('session')->getFlashBag()->add($type, $text);
    }

    /**
     * Returns the pager
     *
     * @param integer        $page    Page
     * @param integer        $perPage Max per page
     * @param Doctrine_Query $query   Query
     *
     * @return \Pagination
     */
    public function getPager($page = 1, $perPage = 10, $query = null)
    {
        $paginator = $this->get('knp_paginator');

        $pagination = $paginator->paginate(
            $query,
            $this->get('request')->query->get('page', 1),
            $perPage
        );

        return $pagination;
    }

After creating this controller, you need to make your apps controller extends the controller you've created.

That way, you avoid duplicated code and alias for popular method.

于 2012-09-13T11:03:30.427 回答
1

您正在寻找的东西可能是参数转换器,它将动作参数直接映射到对象。

以下是描述和一些示例:

http://symfony.com/doc/2.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html

编辑:

一篇有趣的文章中的更多信息:

http://www.adayinthelifeof.nl/2012/08/04/multiparamconverter-for-symfony2/

于 2012-09-13T10:53:58.690 回答
1

你可以做:

private $em;
private $friend;
private $user;

private function init($id==null) {
    $this->em = $this->getDoctrine()->getEntityManager(); 
    $this->friend = $id?$this->em->getRepository('EMMyFriendsBundle:Friend')->find($id):null;
    $this->user = $this->get('security.context')->getToken()->getUser();
}

然后你可以调用你的行动

$this->init($id);

或者

$this->init();

你会有

$this->em;
$this->friend;
$this->user;

可用的。请注意,我允许不设置 $id 参数,因为我猜在某些操作中您不会拥有它。

如果您希望此 init 函数在不同的控制器中可用,请创建一个基本控制器并从中扩展,如另一个答案中所建议的那样。

于 2012-09-13T11:01:09.653 回答
1

如果您仅在几个控制器中拥有该代码,则可以将该代码包装到两者的受保护方法中。

If you think that you can reuse that code in more parts of your application then you should start to think if you need write a validator, use a service or another kind of design

于 2012-09-13T11:01:22.383 回答