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