Symfony CRUD控制器 - 它是如何工作的?

时间:2016-07-26 08:40:55

标签: php symfony doctrine-orm crud

我试图了解Symfoy CRUD控制器是如何工作的,我搜索了很多内容并且无法找到答案。

所以问题是,控制器如何知道哪个实体传递给路由? 例如:

在这个索引路径中,我们调用了doctrine manager,然后从数据库中提取所有注释。

 /**
 * 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,
    ));
}

但是接下来"新"我们没有调用任何doctrine实例.Controller似乎alredy知道哪个实体正在运行。

/**
 * 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(),
    ));
}

我想这是因为第二条路线得到了#34;请求"对象,是存储在其中的实体吗?我想要更深入的解释。

更新:"新"我现在的行动似乎很清楚,这是我想要想象的一个不好的例子,但让我们看看"编辑"动作:

 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(),
    ));
}

这一次,表单已经在其中呈现了数据,但我们只传递了#id;#34;在请求中

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

这次数据来自哪里?好像来自评论对象,它被传递到控制器,但我不知道它来自哪里。 对不起我的愚蠢问题和糟糕的英语!

4 个答案:

答案 0 :(得分:0)

newAction确实在if语句中获得了一个EntityManager实例。

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

然后它使用此管理器来持久保存对象并刷新。

当您加载newAction页面时,它会创建一个新的评论对象,并将其发送到formbuilder。之后,它确保将表单数据放在新的Comment对象上,允许它被保留。

答案 1 :(得分:0)

在newAction函数中:

首先,您的表单与您的实体进行映射:

.workingItemContainer div {
        display: inline-block;
        background-color: #ff9900;
    }

因此,Symfony知道您处理表单中的$comment = new Comment(); $form = $this->createForm('AppBundle\Form\CommentType', $comment); 个对象

然后,当您提交表单时,Comment会识别此内容并立即将提交的数据写回handleRequest()对象

最后,如果object有效,您只需将其保存在数据库中,这要归功于entityManager

所以请求和你的formType之间Symfony知道他想要什么

答案 2 :(得分:0)

我认为如果控制器知道该怎么做,你会让它变得复杂。

实际上,在控制器内部编写的代码定义了控制器的功能。例如:

indexAction应该从数据库中获取注释列表,因此您需要首先获取EntityManager来获取数据。该控制器不处理表格,因为它不是必需的。

newAction应该创建Comment实体的新实例并生成要由用户填写的表单,当提交Request参数捕获所有数据并保存到数据库时。因此,除非您从提交的表单中获取数据,否则您不需要实体经理来处理数据库。

此外,不要假设这些仅限于控制器可以执行的操作,您可以根据您的要求自定义任何控制器。

希望它有意义。

答案 3 :(得分:0)

当我通过generate:doctrine:crud。

创建第一个控制器时,我想知道同样的事情

由于我也是symfony的新手,我所说的仍然基于一些假设。如果我错了,我会感谢任何纠正,因为它有助于我学习。

内核似乎可以识别控制器功能基于类型提示所接受的内容。这样,它确定您的控制器功能是否接受Request对象。 此外,路由的参数将根据提示的类型进行解析和解析。这应该 然后通过Sensio \ Bundle \ FrameworkExtraBundle \ Request \ ParamConverter Class完成魔术。 通过键入提示所需对象的注释,id参数将转换为关联对象并从数据库加载。

顺便说一句,到目前为止我无法弄清楚:在我的路线中是否可以使用与我的功能中不同的参数顺序?

e.g。是可以做到的 /user/{user_id}/{comment_id}

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

希望,它会帮助你。