2016-07-26 3 views
-2

Я пытаюсь понять, как работают контроллеры Symfoy CRUD, я много искал и не могу найти ответы.Контроллер Symfony CRUD - как он работает?

Итак, вопрос в том, как знает контроллер, какой объект передан в маршрут? Например:

На этом маршруте указателя мы вызываем диспетчер учений, а затем вытягиваем все комментарии из базы данных.

/** 
* Lists all Comment entities. 
* 
* @Route("/", name="admin_comment_index") 
* @Method("GET") 
*/ 
public function indexAction() 
{ 
    $em = $this->getDoctrine()->getManager(); 

    $comments = $em->getRepository('AppBundle:Comment')->findAll(); 

    return $this->render('comment/index.html.twig', array(
     'comments' => $comments, 
    )); 
} 

но на следующую «новую» акции мы не называем любую доктрину instances.Controller кажется знает, какой настройки уже объект работает.

/** 
* Creates a new Comment entity. 
* 
* @Route("/new", name="admin_comment_new") 
* @Method({"GET", "POST"}) 
*/ 
public function newAction(Request $request) 
{ 
    $comment = new Comment(); 
    $form = $this->createForm('AppBundle\Form\CommentType', $comment); 
    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     $em = $this->getDoctrine()->getManager(); 
     $em->persist($comment); 
     $em->flush(); 

     return $this->redirectToRoute('admin_comment_show', array('id' => $comment->getId())); 
    } 

    return $this->render('comment/new.html.twig', array(
     'comment' => $comment, 
     'form' => $form->createView(), 
    )); 
} 

Я предполагаю, что это потому, что второй маршрут получает объект «Запрос», является ли объект сохранен в нем? Я хотел бы получить более глубокое объяснение.

UPDATE: «новое» действие теперь мне кажется ясным, что это был плохой пример того, что я пытаюсь понять, но давайте посмотрим на «редактировать» действие:

public function editAction(Request $request, Comment $comment) 
{ 
    $deleteForm = $this->createDeleteForm($comment); 
    $editForm = $this->createForm('AppBundle\Form\CommentType', $comment); 
    $editForm->handleRequest($request); 

    if ($editForm->isSubmitted() && $editForm->isValid()) { 
     $em = $this->getDoctrine()->getManager(); 
     $em->persist($comment); 
     $em->flush(); 

     return $this->redirectToRoute('admin_comment_edit', array('id' => $comment->getId())); 
    } 

    return $this->render('comment/edit.html.twig', array(
     'comment' => $comment, 
     'edit_form' => $editForm->createView(), 
     'delete_form' => $deleteForm->createView(), 
    )); 
} 

На этот раз, форма уже оказана с данными в нем, но мы лишь вскользь «идентификатор» в запросе

<a href="{{ path('admin_comment_edit', { 'id': comment.id }) }}">edit</a> 

откуда данные поступают на этот раз? Похоже, от комментариев объекта, который передается в контроллер, но я не вижу, где это пришли от. Извините за мои вопросы noobish и плохой английский!

+0

Какой объект необходимо извлечь из базы данных в случае «нового»? – Eiko

+0

@Eiko Да, это был плохой пример, как насчет «редактировать» fucntion? Pls смотрит на обновление в моем посте! –

+1

в 'editAction' Symfony загружает объект из переданного id из-за [type-hinting] (http://symfony.com/doc/current/best_practices/controllers.html#using-the-paramconverter) – Jeet

ответ

0

Я думаю, что вы делаете это сложно предполагая контроллер знает, что делать.

На самом деле какой код написан внутри контроллера, определяет, что делает контроллер.Например:

indexAction Предполагается, что вы получите список комментариев из базы данных, поэтому вам нужно сначала получить EntityManager для получения данных. этот контроллер не имеет дело с формой, поскольку это не требуется.

newAction предполагается создать новый экземпляр Comment объекта и создания формы должны быть заполнены пользователем, когда они представляются Request параметр перехватывает все данные и сохраняет в базе данных. следовательно, если вы не получаете данные из представленной формы, вам не нужен менеджер объектов для работы с базой данных.

Кроме того, не предполагайте, что они ограничены тем, что может делать контроллер. Вы можете настроить любой контроллер по вашему требованию.

Надеюсь, что это имеет смысл.

+0

Спасибо, мне кажется намного яснее, я добавил обновление для публикации, пожалуйста, посмотри на него! –

0

newAction действительно получает экземпляр EntityManager внутри оператора if.

if ($form->isSubmitted() && $form->isValid()) { 
    $em = $this->getDoctrine()->getManager(); 
//... 

И затем он использует этого менеджера для сохранения объекта и промывки.

Когда вы загружаете страницу newAction, она создала новый объект комментария и отправляет это форматору. После этого он гарантирует, что данные формы будут помещены в новый объект Comment, что позволит сохранить его.

+0

Да, это был плохой пример, как насчет «редактировать» fucntion? Pls смотрит на обновление в моем посте! –

0

В функции newAction:

Во-первых, ваша форма сопоставлен с лица:

$comment = new Comment(); 
$form = $this->createForm('AppBundle\Form\CommentType', $comment); 

Так Symfony знает, что вы имеете дело с Comment объектами в виде

Затем, когда вы представите формы, handleRequest() признает это и сразу же записывает представленные данные обратно в объект Comment

Наконец, если объект действительно, вы просто должны сохранить его в базе данных, благодаря EntityManager

Так между запросом и вашим formType Symfony знает, что он хочет

+0

Да, это был плохой пример, как насчет «редактировать» fucntion? Pls смотрит на обновление в моем посте! –

0

Мне было интересно, когда я создал первый контроллер через generate: doctrine: crud.

Поскольку я новичок в symfony, я утверждаю, что все еще основывается на некоторых предположениях. Если я ошибаюсь, я благодарен за любую коррекцию, поскольку это помогает мне учиться.

Ядро, по-видимому, распознает функцию вашего контроллера, основанную на типе намека. Таким образом, он определяет, принимает ли ваша функция контроллера объект Request или нет. Кроме того, аргументы маршрута разрешаются и анализируются относительно намеченных типов. Это должно быть Магия затем выполняется через Sensio \ Bundle \ FrameworkExtraBundle \ Request \ ParamConverter Class. По типу, намекающему на ваш желаемый объект Комментарий, параметр id преобразуется в связанный объект и загружается из вашей базы данных.

Кстати, что я не мог понять до сих пор: возможно ли использовать другой порядок параметров в моем маршруте, чем в моей функции?

например. это можно сделать /user/{user_id}/{comment_id} с

public function funWithUserComment(Request $request, Comment $comment, User $user) 
{ 
    //.. 
} 

Надежда, это поможет вам хотя.