Doctrine,MVC,Symfony:我可以在哪里使用Doctrine?我可以在控制器中使用它吗?

时间:2014-07-01 10:46:45

标签: php symfony model-view-controller doctrine-orm doctrine

让我们看看我的建筑师:

型号:

// links table: (ID, LINKNAME)
Class Link extends Link_base
{
}

控制器:

public function index()
{
    $this->links = new Doctrine - here I build the query, SELECT, ORDER BY, etc
}

在这个例子中,模型可以保持为空(没有严重的逻辑),我只需要一个带有顺序的选择。我不确定我是否可以在控制器中使用Doctrine - 我应该像这样重新制作吗?

Class Link extends Link_base
{
    public function getLinks()
    {
        return new Doctrine - here I build the query, SELECT, ORDER BY, etc;
    }
}

控制器:

public function index()
{
    $this->links = Links::getLinks();
}

我不确定哪种方式似乎没问题。当然,当选择需要更复杂的格式化todo-s时,它会转到模型或帮助器 - 但我觉得我只是制作了一个新的(不必要的)层。此getLinks()仅使用一次。换句话说:Doctrine可能只在模型中使用,或者也可以在控制器中使用?

1 个答案:

答案 0 :(得分:2)

您的实体(或模型,如果您更喜欢该名称)应该知道 如何从数据库中保存/检索它们。它们应该只是简单的PHP对象,只包含许多属性(对应于数据库列)及其getter和setter。

(如果您有兴趣,请阅读single responsibility principle,其中说明每个班级应该只有一个,而且只有一个责任。如果您让您的实体负责存储数据知道如何在数据库中保存数据,当其中一个更改时,您将有更大的机会引入错误。)

您可以从控制器内部获取实体:

<?php

namespace Your\Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class LinkController extends Controller
{
    public function fooAction()
    {
        $links = $this->getDoctrine()
            ->getRepository('YourBundle:Link')
            ->findAll();

        // do something with the result, like passing it to a template
    }
}

但是,您可能需要更复杂的查询(包括排序和过滤),您可能需要从多个控制器运行该查询。在这种情况下,您不希望将该逻辑复制到多个控制器,您希望将该逻辑保留在一个中心位置。

为此,请创建一个存储库:

<?php

namespace Your\Bundle\Repository;

use Doctrine\ORM\EntityRepository;

class LinkRepository extends EntityRepository
{
    public function findAllOrderedByName()
    {
        return $this->getEntityManager()
            ->createQuery(
                'SELECT l FROM YourBundle:Link l ORDER BY l.name ASC'
            )
            ->getResult();
    }
}

将存储库类添加到映射中:

Your\Bundle\Entity\Link:
    type: entity
    repositoryClass: Your\Bundle\Repository\LinkRepository

(如果您使用的是XML或注释而不是Yaml,请查看Symfony's documentation about custom repositories

现在在您的控制器中,您只需更新fooAction方法,以便它使用您的自定义存储库方法:

public function fooAction()
{
    $links = $this->getDoctrine()
        ->getRepository('YourBundle:Link')
        ->findAllOrderedByName();
}

有关更多信息,Symfony的文档包含great article about Doctrine。如果你还没有这样做,我肯定会建议你阅读它。