我使用的是Symfony(3.2.3)和Doctrine ORM(2.5.6)的当前版本,我仍在努力思考如何正确处理getEntityManager()
和相关方法的弃用。
例如,当前文档指出,这是创建查询生成器实例的方法:
$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$queryBuilder = $repository->createQueryBuilder('p')
但在我看来(我的IDE似乎也同意),getRepository()
被类型提示返回ObjectRepository
的实例,方法createQueryBuilder()
没有在该接口中声明,而是在实现类EntityRepository
中声明。
另一个例子是在控制器中显式启动事务:
$this->getDoctrine()->getEntityManager()->getConnection()->beginTransaction()
我应该调用getManager()
而不是getEntityManager()
,因为后一种方法已被弃用。但是getManager()
被类型提示为返回不声明getConnection()
的ObjectManager
的实例。
PHP作为PHP,代码似乎在所有情况下都能工作,但我和IDE都有一种不安的感觉。那么,在Symfony 3中创建查询生成器或开始事务的正确方法是什么?我是不是错过了什么?
DoctrineCommon
中定义的通用接口,例如ObjectManager
或ObjectRepository
。
在Symfony中,getDoctrine()
方法从DoctrineBundle
返回Registry
类的实例(默认情况下)。简而言之,此服务包含所有可用的连接和实体管理器。他的方法getManager()
在DoctrineCommon
中实现,它不知道什么类型的数据映射器,并将返回类型声明为泛型ObjectManager
。
为了避免IDE警告,您可以显式定义内联PHPDoc。Netbeans和PHPStorm都支持它。
/* @var $entityManager DoctrineORMEntityManager */
$entityManager = $this->getDoctrine()->getManager();
另一种解决方案是一种简单的辅助方法:
public function getEntityManager(): EntityManager
{
return $this->getDoctrine()->getManager();
}
对于上述解决方案,我们假设请求的服务实际上来自ORM,因此是一种类型下转换:实际的类将仅在运行时检查。为了类型安全,您可以直接在服务中注入实体管理器。
如果您的问题只是您的IDE,您可以告诉它返回的不是ObjectRepository,例如:
/** @var ProductRepository $repository */
$repository = $this->getDoctrine()->getRepository('AppBundle:Product');
$queryBuilder = $repository->createQueryBuilder('p');
因为你知道这就是你会得到的。
试试这个:
$queryBuilder=$this->getDoctrine()->getManager()->getRepository('AppBundle:Product')->createQueryBuilder('p');如果您正在使用phpstorm或忽略您的ide ,请更新您的symfony插件