Reputation: 3169
I am using PHPStan with its Doctrine extension.
I have a custom entity repository called App\Repository\Doctrine\UserRepository
with the @extends
doc block:
/**
* @extends \Doctrine\ORM\EntityRepository<\App\Entity\User>
*/
class UserRepository extends EntityRepository implements IUserRepository
{
public function customRepositoryMethod()
{
// ...
}
}
In a controller, this code:
public function getUserMatches(EntityManager $em)
{
$userRepo = $em->getRepository(\App\Entity\User::class);
$userRepo->customRepositoryMethod();
}
...results in this PHPStan error:
Call to an undefined method Doctrine\ORM\EntityRepository<meQ\Entity\User>::customRepositoryMethod().
Thanks to phpstan-doctrine, static analysis knows that $em->getRepository(User::class)
returns a EntityRepository<User>
.
However, it does not know to consider the custom repository class UserRepository
as the implementation of that generic type.
How do I DocBlock the UserRepository class, or otherwise configure PHPStan, so that it interprets UserRepository
as the implementation of EntityRepository<User>
?
I've also tried this DocBlock on UserRepository
to no avail:
/**
* @implements \Doctrine\ORM\EntityRepository<\App\Entity\User>
*/
Upvotes: 4
Views: 2869
Reputation: 456
I think you missed this action while configuring your PHPStan: add this config to the phpstan.neon
includes:
- vendor/phpstan/phpstan-doctrine/extension.neon
- vendor/phpstan/phpstan-doctrine/rules.neon
Upvotes: 0
Reputation: 47630
PhpStan has no way of knowing EntityManager::getRepository()
is going to return your custom method.
Either add a @var
annotation right there:
/** @var UserRepository $userRepo */
$userRepo = $em->getRepository(\App\Entity\User::class);
Or better yet, just inject the UserRepository
, not the whole EntityManager
:
public function getUserMatches(UserRepository $userRepository)
{
$userRepository->customRepositoryMethod();
}
The above would work with PhpStan or any static analysis tool out of the box. (And, injecting the specific repository instead of the Entity Manager is a better practice in any case).
But if not, you can always try installing the Doctrine Extensions for PHPStan, which may help the tool understand the codebase in relationship to Doctrine ORM.
If you are already using the Doctrine Extensions, note that from what I gather in the docs it's only able to extract typing if your mapping configuration is provided via annotations. If you configurate ORM mappings via XML (or YAML, in older versions of Doctrine), then I think the Extensions won't be able to extract the typing data, and the above solutions will be your only way to go.
Upvotes: 5