PHPStan 不使用自定义实体存储库

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)

yiv*_*ivi 5

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 映射,那么我认为扩展将无法提取键入数据,并且上述解决方案将是您唯一的方法。

  • 我和@harvident 在一起。根据 [PHPStan Doctrine 文档](https://github.com/phpstan/phpstan-doctrine),`为 Doctrine\ORM\EntityManager::getRepository() 提供正确的返回值`。这对于扩展来说是完全合理的。我猜扩展未正确加载。 (2认同)