ama*_*ert 4 php doctrine static-analysis symfony phpstan
我正在使用 PHPStan 及其 Doctrine 扩展。
我有一个使用 doc 块调用的自定义实体存储App\Repository\Doctrine\UserRepository库@extends:
/**
* @extends \Doctrine\ORM\EntityRepository<\App\Entity\User>
*/
class UserRepository extends EntityRepository implements IUserRepository
{
public function customRepositoryMethod()
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在控制器中,这段代码:
public function getUserMatches(EntityManager $em)
{
$userRepo = $em->getRepository(\App\Entity\User::class);
$userRepo->customRepositoryMethod();
}
Run Code Online (Sandbox Code Playgroud)
...导致此 PHPStan 错误:
Call to an undefined method Doctrine\ORM\EntityRepository<meQ\Entity\User>::customRepositoryMethod().
Run Code Online (Sandbox Code Playgroud)
感谢 phpstan-doctrine,静态分析知道$em->getRepository(User::class)返回一个EntityRepository<User>.
但是,它不知道将自定义存储库类UserRepository视为该泛型类型的实现。
如何 DocBlock UserRepository 类,或以其他方式配置 PHPStan,以便它解释UserRepository为 的实现EntityRepository<User>?
我也尝试过这个 DocBlock,但UserRepository没有成功:
Call to an undefined method Doctrine\ORM\EntityRepository<meQ\Entity\User>::customRepositoryMethod().
Run Code Online (Sandbox Code Playgroud)
PhpStan 无法知道EntityManager::getRepository()是否会返回您的自定义方法。
@var要么在此处添加注释:
/** @var UserRepository $userRepo */
$userRepo = $em->getRepository(\App\Entity\User::class);
Run Code Online (Sandbox Code Playgroud)
或者更好的是,只需注入UserRepository,而不是整个EntityManager:
public function getUserMatches(UserRepository $userRepository)
{
$userRepository->customRepositoryMethod();
}
Run Code Online (Sandbox Code Playgroud)
上述内容适用于 PhpStan 或任何开箱即用的静态分析工具。(并且,在任何情况下注入特定存储库而不是实体管理器都是更好的做法)。
但如果没有,您始终可以尝试安装PHPStan 的 Doctrine 扩展,这可能有助于该工具理解与 Doctrine ORM 相关的代码库。
如果您已经在使用 Doctrine Extensions,请注意,根据我在文档中收集的信息,如果您的映射配置是通过注释提供的,它只能提取类型。如果您通过 XML(或 YAML,在旧版本的 Doctrine 中)配置 ORM 映射,那么我认为扩展将无法提取键入数据,并且上述解决方案将是您唯一的方法。