use Doctrine\Persistence\ManagerRegistry;
class SomeController {
public function __construct(private ManagerRegistry $doctrine) {}
public function someAction(Request $request) {
// access Doctrine
$this->doctrine;
}
}
// 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());
}
}
<?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');
}
...
}
<?php
namespace App\Controller;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Persistence\ObjectManager;
use Symfony\Contracts\Service\Attribute\Required;
trait EntityManagerTrait
{
protected readonly ManagerRegistry $managerRegistry;
#[Required]
public function setManagerRegistry(ManagerRegistry $managerRegistry): void
{
// @phpstan-ignore-next-line PHPStan complains that the readonly property is assigned outside of the constructor.
$this->managerRegistry = $managerRegistry;
}
protected function getDoctrine(?string $name = null, ?string $forClass = null): ObjectManager
{
if ($forClass) {
return $this->managerRegistry->getManagerForClass($forClass);
}
return $this->managerRegistry->getManager($name);
}
}
然后再
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\Foobar;
class SomeController extends AbstractController
{
use EntityManagerTrait
public function someAction()
{
$result = $this->getDoctrine()->getRepository(Foobar::class)->doSomething();
// ...
}
}
5条答案
按热度按时间aelbi1ox1#
如上所述here:
不要使用这些快捷方式,而是在构造函数或控制器方法中注入相关服务。
您需要使用依赖注入。
对于给定的控制器,只需在控制器的构造函数上注入
ManagerRegistry
。hl0ma9xz2#
您可以使用实体管理器接口$entityManager:
ljsrvy3e3#
根据@yivi的回答和文档中提到的,您也可以按照下面的示例,直接在所需的方法中注入
Doctrine\Persistence\ManagerRegistry
:rqcrx0a64#
在控制器中添加代码,不改变控制器逻辑
阅读更多https://symfony.com/doc/current/service_container/service_subscribers_locators.html#including-services
7rfyedvj5#
在我的例子中,依赖于基于构造函数或方法的自动配置不够灵活。
我有一个trait,很多Controller都使用它来定义自己的自动配置。这个trait提供了一个从数据库中获取一些数字的方法。我不想把trait的功能和controller的自动配置设置紧密结合起来。
我创造了另一个特征,我可以在任何需要访问教义的地方添加它。额外的好处是?它仍然是一个合法的自动安装方法:
然后再
如果您像我一样有多个管理器,也可以使用
getDoctrine()
参数来获取正确的管理器。