【问题标题】:Symfony CRUD controller - how does it works?Symfony CRUD 控制器 - 它是如何工作的?
【发布时间】:2016-07-26 08:40:54
【问题描述】:

我正在尝试了解 Symfoy CRUD 控制器的工作原理,我在 Google 上搜索了很多,但找不到任何答案。

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

在这个索引路由中,我们调用了学说管理器,然后从数据库中拉出所有的 cmets。

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

但在下一个“新”操作中,我们不会调用任何学说实例。控制器似乎已经知道哪个实体正在运行。

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

我猜这是因为第二条路由获得了“请求”对象,实体是否存储在其中?我想有更深入的解释。

更新:“新”动作现在对我来说似乎很清楚,这是我试图弄清楚的一个坏例子,但让我们看看“编辑”动作:

 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”

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

这次的数据来自哪里?似乎来自评论对象,它被传递到控制器中,但我看不出它来自哪里。 对不起我的问题和糟糕的英语!

【问题讨论】:

  • 如果是“new”,需要从数据库中获取什么对象?
  • @Eiko 是的,这是一个不好的例子,那么“编辑”功能呢?请看我帖子中的更新!
  • in editAction Symfony 加载由于 type-hinting 而传递的 id 中的实体
  • @Jeet 非常感谢,正是我需要的信息。
  • 很高兴,它帮助了你。 :)

标签: php symfony doctrine-orm crud


【解决方案1】:

我认为假设控制器知道该怎么做,你会让事情变得复杂。

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

indexAction 应该从数据库中获取 cmets 列表,因此您需要先获取 EntityManager 才能获取数据。这个控制器不处理表单,因为它不是必需的。

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

另外,不要假设这些仅限于控制器可以做什么,您可以根据需要自定义任何控制器。

希望它有意义。

【讨论】:

  • 谢谢,对我来说似乎更清楚了,我已添加更新以发布,请看!
【解决方案2】:

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

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

然后它使用这个管理器来持久化对象并刷新。

当您加载newAction 页面时,它会创建一个新的评论对象,并将其发送到表单构建器。之后,它会确保将表单数据放置到新的 Comment 对象上,使其得以持久化。

【讨论】:

  • 是的,这是一个不好的例子,那么“编辑”功能呢?请看我帖子中的更新!
【解决方案3】:

在newAction函数中:

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

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

所以 Symfony 知道您处理表单中的 Comment 对象

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

最后,如果对象是有效的,你只需要通过 entityManager 将它保存在数据库中

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

【讨论】:

  • 是的,这是一个不好的例子,那么“编辑”功能呢?请看我帖子中的更新!
【解决方案4】:

当我通过 generate:doctrine:crud 创建第一个控制器时,我也有同样的疑惑。

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

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

顺便说一句,到目前为止我还没有弄清楚:是否可以在我的路由中使用与我的函数中不同的参数顺序?

例如有可能吗 /user/{user_id}/{comment_id}

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

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2013-03-21
    • 2019-01-15
    • 2014-04-13
    • 1970-01-01
    相关资源
    最近更新 更多