phpstan-doctrine
phpstan-doctrine copied to clipboard
Use DTO in a query builder
Can the following code work without manually defining the return type, i.e adding /** @var UserDto[] */?
final class Repository
{
public function __construct(
private EntityManagerInterface $em
) {
}
/**
* @return UserDto[]
*/
public function findAll(): array
{
$qb = $this->em->createQueryBuilder()
->select(\sprintf('NEW %s(u.id, u.email)', UserDto::class))
->from(User::class, 'u')
->getQuery();
/** @var UserDto[] */
return $qb->getResult();
}
public function findByEmail(string $email): ?UserDto
{
$qb = $this->em->createQueryBuilder()
->select(\sprintf('NEW %s(u.id, u.email)', UserDto::class))
->from(User::class, 'u')
->where('u.email = :email')
->setParameter('email', $email)
->getQuery();
/** @var UserDto|null */
return $qb->getOneOrNullResult();
}
}
This should work fine. Have you configured objectManagerLoader (see README)?
Readme states that NEW should work. Are you suggesting it does not?
Most DQL features are supported, including GROUP BY, DISTINCT, all flavors of JOIN, arithmetic expressions, functions, aggregations, NEW, etc.
Yeah, I've added tests/object-manager.php. I still got an error
Method Repository::findByEmail() should return UserDto|null but returns mixed.
The first method should have no issue.
Are you on latest versions of PHPStan and phpstan-doctrine?
Yeah, tested on the latest version
phpstan: 1.10.64
phpstan-doctrine: 1.3.64
There are many test cases for this scenario starting on this line https://github.com/phpstan/phpstan-doctrine/blob/0871900872abde0d93e4bbd8c681a9985bcd927e/tests/Type/Doctrine/Query/QueryResultTypeWalkerTest.php#L942
I guess you might have to reproduce your issue either in tests here (probably in QueryBuilderGetQueryDynamicReturnTypeExtensionTest), or in a separate repository.
I'll try that