Symfony 将 Doctrine Manager 实例注入控制器方法参数

Symfony injected Doctrine Manager instance to controller method arguments

在 Controller 中,您可以使用以下内容定义更新操作:

    /**
     * @Route("/product/edit/{id}")
     */
    public function updateAction(Product $product)
    {
     // product is auto select from database by id and inject to controller action.
    }

自动注入很方便,但是如何将DoctrineManager实例注入controller action,不用手动创建DoctrineManager实例会更方便。如下所示:

    /**
     * @Route("/product/edit/{id}")
     */
    public function updateAction(Product $product, ObjectManager $em)
    {
       $product->setName("new name");
       $em->flush();
    }

代替长编码:

/**
 * @Route("/product/edit/{id}")
 */
public function updateAction($id)
{
    $em = $this->getDoctrine()->getManager();
    $product = $em->getRepository(Product::class)->find($id);

    if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$id
        );
    }

    $product->setName('New product name!');
    $em->flush();

    return $this->redirectToRoute('app_product_show', [
        'id' => $product->getId()
    ]);
}

我还没有尝试过 Symfony4,但是根据官方的 symfony 文档,有基于动作的依赖注入,所以你应该能够通过将服务接口声明为动作的参数来使用服务。

https://symfony.com/doc/4.1/controller.html#controller-accessing-services

If you need a service in a controller, just type-hint an argument with its class (or interface) name. Symfony will automatically pass you the service you need:

所以在你的情况下它应该是这样的:

/**
  * @Route("/product/edit/{id}")
  */
public function updateAction(Product $product, EntityManagerInterface $em)
{
    $product->setName("new name");
    $em->flush();
}