Doctrine, MVC, Symfony: где я могу использовать Doctrine? Могу ли я использовать его в контроллере?

#php #symfony #model-view-controller #doctrine-orm #doctrine

#php #symfony #модель-представление-контроллер #doctrine-orm #доктрина

Вопрос:

Давайте посмотрим на моего архитектора:

Модель:

 // 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
}
  

в этом примере модель может оставаться пустой (без серьезной логики), все, что мне нужно, это выбрать с order by . Я не уверен, что могу использовать 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();
}
  

Я не уверен, какой способ подходит. Конечно, при выборе требуется более сложная задача форматирования, она переходит к модели или помощнику — но я чувствую, что я только что создал новый (ненужный) слой. Этот getLinks() использовался только один раз. Другими словами: Doctrine может использоваться только в модели, или его можно использовать и в контроллерах?

Комментарии:

1. Может — да; должен — НЕТ

2. не могли бы вы подтвердить это примером или источником?

3. Doctrine2 — это платформа абстракции персистентности (реализующая шаблон отображения данных ), и ее никогда не следует использовать на уровне персистентности. Вместо этого его следует использовать в сервисах для хранения и извлечения данных из объектов домена (на уровне модели).

Ответ №1:

Ваши объекты (или модели, если вы предпочитаете это имя) должны не знать, как они сохраняются в / извлекаются из базы данных. Они должны быть просто простыми объектами PHP, содержащими только ряд свойств (соответствующих столбцам базы данных) и их получатели и установщики.

(Если вам интересно, прочитайте немного о принципе единой ответственности, который гласит, что у каждого класса должна быть одна и только одна ответственность. Если вы назначаете свои объекты ответственными за хранение данных и знаете, как сохранить эти данные в базе данных, у вас будет больше шансов внести ошибки при изменении одной из этих вещей.)

Вы можете извлекать объекты из своего контроллера:

 <?php

namespace YourBundleController;

use SymfonyBundleFrameworkBundleControllerController;

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 YourBundleRepository;

use DoctrineORMEntityRepository;

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

И добавьте класс репозитория в свое отображение:

 YourBundleEntityLink:
    type: entity
    repositoryClass: YourBundleRepositoryLinkRepository
  

(проверьте документацию Symfony о пользовательских репозиториях, используете ли вы XML или аннотации вместо Yaml)

Теперь в вашем контроллере вы можете просто обновить свой fooAction метод, чтобы он использовал ваш пользовательский метод репозитория:

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

Для получения дополнительной информации в документации Symfony есть отличная статья о Doctrine. Если вы еще этого не сделали, я бы определенно рекомендовал прочитать его.

Комментарии:

1. Красиво объяснено. Это напоминает о полезности репозиториев.