phpstan-doctrine icon indicating copy to clipboard operation
phpstan-doctrine copied to clipboard

QueryBuilder::select() with multiple arguments not understood

Open jlherren opened this issue 3 years ago • 1 comments

I have a method as follows:

protected function foo(): void {
    $qb = $this->entityManager->createQueryBuilder();
    if (mt_rand(0, 1) === 0) {
        $qb->select('e.f1', 'e.f2');
    }
    else {
        $qb->select('e.f3', 'e.f4');
    }
    \PHPStan\dumpType($qb);
    $qb->select('e.f5', 'e.f6');
}

I get the following output:

  117    Dumped type: Doctrine\ORM\QueryBuilder|Doctrine\ORM\QueryBuilder
  118    Method Doctrine\ORM\QueryBuilder::select() invoked with 2 parameters, 0-1 required.

I only marginally know how the query builder code works, but I xdebugged it as far as to see that the union is done between two BranchingQueryBuilderType instances and they are not considered equal due to different methods having been called on them. So not collapsing the union seems expected, but then maybe the code that validates the select() call cannot handle unions or something like that.

I imagine that this is hard to reproduce, since it might depend on the exact Doctrine configuration. Let me know if I should attempt to create a full stand-alone example that triggers the issue.

Using phpstan/phpstan-doctrine 1.3.12 and phpstan/phpstan 1.8.4.

jlherren avatar Sep 05 '22 15:09 jlherren

I came on to this issue as well. Under the hood the select function performs $selects = is_array($select) ? $select : func_get_args(); to ensure the parameters are passed on as an array. However the docblock above it says

     * <code>
     *     $qb = $em->createQueryBuilder()
     *         ->select('u', 'p')
     *         ->from('User', 'u')
     *         ->leftJoin('u.Phonenumbers', 'p');
     * </code>```
So it endorses the usage.

ricohumme avatar Oct 04 '23 13:10 ricohumme