New alternative for getDoctrine() in Symfony 5.4 and up
Asked Answered
O

4

18

As my IDE points out, the AbstractController::getDoctrine() method is now deprecated.

I haven't found any reference for this deprecation neither in the official documentation nor in the Github changelog.

What is the new alternative or workaround for this shortcut?

Odoric answered 3/12, 2021 at 8:54 Comment(0)
A
37

As mentioned here:

Instead of using those shortcuts, inject the related services in the constructor or the controller methods.

You need to use dependency injection.

For a given controller, simply inject ManagerRegistry on the controller's constructor.


use Doctrine\Persistence\ManagerRegistry;

class SomeController {

    public function __construct(private ManagerRegistry $doctrine) {}

    public function someAction(Request $request) {
        // access Doctrine
        $this->doctrine;
    }
} 
Aronow answered 3/12, 2021 at 9:5 Comment(3)
May I ask the difference between EntityManagerInterface and ManagerRegistry and why the last is a better option?Odoric
I don't if it's "better". It's simply equivalent to the old behavior of getDoctrine(). It's fine to inject the EntityManagerInterface as well. See what works better for you, depending of your needs. Check what each sevice provides.Aronow
ManagerRegistry allows you to fetch non-default EntityManagerInterface managers, if you use them. If you only have one manager, injecting EntityManagerInterface is fine. Check the source code for both interfaces to see what the difference is. For example, you can't persist or flush directly using a ManagerRegistry object. You have to do that through the object produced by ManagerRegistry::getManager(). At the end of the day, it doesn't make much difference which one you go with. Go with the one less verbose, or better fitting to your use case.Antitoxic
O
5

You can use EntityManagerInterface $entityManager:

public function delete(Request $request, Test $test, EntityManagerInterface $entityManager): Response
{
    if ($this->isCsrfTokenValid('delete'.$test->getId(), $request->request->get('_token'))) {
        $entityManager->remove($test);
        $entityManager->flush();
    }

    return $this->redirectToRoute('test_index', [], Response::HTTP_SEE_OTHER);
}
Opine answered 7/12, 2021 at 13:56 Comment(0)
A
3

As per the answer of @yivi and as mentionned in the documentation, you can also follow the example below by injecting Doctrine\Persistence\ManagerRegistry directly in the method you want:

// src/Controller/ProductController.php
namespace App\Controller;

// ...
use App\Entity\Product;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    /**
     * @Route("/product", name="create_product")
     */
    public function createProduct(ManagerRegistry $doctrine): Response
    {
        $entityManager = $doctrine->getManager();

        $product = new Product();
        $product->setName('Keyboard');
        $product->setPrice(1999);
        $product->setDescription('Ergonomic and stylish!');

        // tell Doctrine you want to (eventually) save the Product (no queries yet)
        $entityManager->persist($product);

        // actually executes the queries (i.e. the INSERT query)
        $entityManager->flush();

        return new Response('Saved new product with id '.$product->getId());
    }
}
Allista answered 17/2, 2022 at 9:53 Comment(0)
C
1

Add code in controller, and not change logic the controller

<?php
//...
use Doctrine\Persistence\ManagerRegistry;
//...
class AlsoController extends AbstractController
{
    public static function getSubscribedServices(): array
    {
        return array_merge(parent::getSubscribedServices(), [
            'doctrine' => '?'.ManagerRegistry::class,
        ]);
    }
    protected function getDoctrine(): ManagerRegistry
    {
        if (!$this->container->has('doctrine')) {
            throw new \LogicException('The DoctrineBundle is not registered in your application. Try running "composer require symfony/orm-pack".');
        }
        return $this->container->get('doctrine');
    }
...
}

read more https://symfony.com/doc/current/service_container/service_subscribers_locators.html#including-services

Colubrid answered 19/9, 2022 at 1:24 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Enugu

© 2022 - 2024 — McMap. All rights reserved.