如何正确获取Symfony 3中的EntityManager?

cg.*_*cg. 4 php symfony doctrine-orm

我正在使用当前版本的Symfony(3.2.3)和Doctrine ORM(2.5.6),我仍然试图正确地处理如何正确处理弃用getEntityManager()和相关方法.

例如,当前文档指出这是创建查询构建器实例的方法:

$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$queryBuilder = $repository->createQueryBuilder('p')
Run Code Online (Sandbox Code Playgroud)

但是我看到它(以及我的IDE似乎同意)的方式getRepository()是类型提示返回一个实例,ObjectRepository并且该方法createQueryBuilder()未在该接口中声明,而是在实现类中EntityRepository.

另一个例子是在控制器中显式启动事务:

$this->getDoctrine()->getEntityManager()->getConnection()->beginTransaction()
Run Code Online (Sandbox Code Playgroud)

我应该调用getManager()而不是getEntityManager()因为后一种方法已被弃用.但是getManager()类型暗示返回一个ObjectManager未声明的实例getConnection().

PHP是PHP的代码似乎仍然适用于所有情况,但我的IDE和我留下了一种不安的感觉.那么,在Symfony 3中创建查询构建器或开始事务的正确方法是什么?我错过了什么吗?

Tim*_*rib 8

Doctrine有两种类型的数据映射器:RDBMS 的ORM和面向文档的DB 的ODM(主要用于MongoDB).数据映射器尝试以一种持久性 - 无知的方式实现,并且它们都实现了在Doctrine\Common诸如ObjectManager或中定义的通用接口ObjectRepository.

在Symfony中,该getDoctrine()方法RegistryDoctrineBundle(默认情况下)返回类的实例.简而言之,该服务包含所有可用的连接和实体管理器.他的方法getManager()实现了Doctrine\Common,它不知道什么类型的数据映射器并将返回类型声明为泛型ObjectManager.

要避免IDE警告,您可以显式定义内联PHPDoc.Netbeans和PHPStorm都支持它.

/* @var $entityManager Doctrine\ORM\EntityManager */
$entityManager = $this->getDoctrine()->getManager();
Run Code Online (Sandbox Code Playgroud)

其他解决方案是一个简单的帮助方法:

public function getEntityManager(): EntityManager
{
    return $this->getDoctrine()->getManager();
}
Run Code Online (Sandbox Code Playgroud)

通过上述解决方案,我们假设所请求的服务实际上来自ORM,因此是一种类型的向下转换:仅在运行时检查实际类.对于类型安全,您可以直接在服务中注入实体管理器.