Php Symfony CRUD控制器-如何工作?

Php Symfony CRUD控制器-如何工作?,php,symfony,doctrine-orm,crud,Php,Symfony,Doctrine Orm,Crud,我试图了解Symfoy CRUD控制器是如何工作的,我在谷歌上搜索了很多,但找不到任何答案 所以问题是,控制器如何知道哪个实体被传递到路由? 例如: 在这个索引路径中,我们调用条令管理器,然后从数据库中提取所有注释 /** * Lists all Comment entities. * * @Route("/", name="admin_comment_index") * @Method("GET") */ public function indexAction() { $e

我试图了解Symfoy 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,
    ));
}
但在下一个“新”行动中,我们不会调用任何条令实例。控制器似乎已经知道哪个实体正在运行

/**
 * 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(),
    ));
}
我猜这是因为第二条路径得到了“请求”对象,实体是否存储在其中?我想有更深入的解释

更新:“新建”操作现在对我来说似乎很清楚,这是一个很糟糕的例子,但让我们看看“编辑”操作:

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

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

这次数据来自何处?看起来像是来自comment对象,它被传递到控制器中,但我看不出它来自何处。
抱歉,我的问题太多,英语太差了!

newAction
在if语句中得到了EntityManager实例

if ($form->isSubmitted() && $form->isValid()) {
    $em = $this->getDoctrine()->getManager();
//...
然后它使用这个管理器来持久化对象并刷新

加载
newAction
页面时,它会创建一个新的注释对象,并将其发送给formbuilder。之后,它会确保表单数据被放置到新的注释对象上,从而允许它被持久化。

在newAction函数中:

首先,将表单映射到实体:

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

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

最后,如果对象有效,您只需借助entityManager将其保存在数据库中即可


因此,在请求和表单类型之间,Symfony知道他想要什么,我认为如果控制器知道该做什么,您会使事情变得复杂

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

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

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

 /**
 * 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,
    ));
}
此外,不要假设这些限制仅限于控制器的功能,您可以根据需要定制任何控制器


希望它有意义。

当我通过generate:doctor:crud创建第一个控制器时,我也在想同样的问题

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

内核似乎根据类型暗示识别控制器函数接受的内容。通过这一点,它确定控制器函数是否接受请求对象。 此外,路由中的参数将根据提示类型进行解析 然后通过Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter类完成这一魔术。 通过类型提示所需的对象注释,id参数将转换为关联对象并从数据库中加载

 /**
 * 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,
    ));
}
顺便问一下,到目前为止我还没有弄明白的是:在我的路由中使用的参数顺序是否可能与在函数中使用的参数顺序不同

e、 有可能吗
/user/{user\u id}/{comment\u id}
具有


希望,这对您有所帮助。

如果是“新建”,需要从数据库中获取什么对象?@Eiko是的,这是一个糟糕的示例,“编辑”呢“他妈的?请看我帖子中的更新!在
editAction
Symfony中,从传递的id加载实体,因为@Jeet非常感谢,这正是我需要的信息。很高兴,它帮助了你。:)谢谢,对我来说似乎更清楚了,我在帖子中添加了一个更新,请看!是的,这是个坏例子,“编辑”功能怎么样?请看我帖子中的更新!是的,这是个坏例子,“编辑”功能怎么样?请看我帖子中的更新!