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

Support `AbstractQuery::getSingleScalarResult`

Open ruudk opened this issue 1 year ago • 2 comments

It appears that getSingleScalarResult() currently always returns bool|float|int|string|null.

If I have the following query:

$result = $this->createQueryBuilder('u')
            ->select('COUNT(u.id)')
            ->where('u.is_deleted = false')
            ->getQuery()
            ->getSingleScalarResult();

\PHPStan\assertType($result, 'bool|float|int|string|null');

But when I do getResult() it works properly:

$result = $this->createQueryBuilder('u')
            ->select('COUNT(u.id)')
            ->where('u.is_deleted = false')
            ->getQuery()
            ->getSingleScalarResult();

\PHPStan\assertType($result, 'list<array{1: int<0, max>}>');

I wonder why we cannot support getSingleScalarResult? I created the following helper:

/**
 * @template TValue of scalar
 * @param list<array{1: TValue}> $results
 *
 * @return TValue
 */
protected function getSingleScalarResult(array $results) : bool | float | int | string
{
    return $results[0][array_key_first($results[0])];
}

And now this works great:

$result = $this->getSingleScalarResult($this->createQueryBuilder('u')
            ->select('COUNT(u.id)')
            ->where('u.is_deleted = false')
            ->getQuery()
            ->getResult());

\PHPStan\assertType($result, 'int<0, max>');

Am I being naive here and is there a flaw with my solution or would it be possible to support it 😁?

/cc @arnaud-lb @janedbal

References:

  • https://github.com/phpstan/phpstan-doctrine/issues/276

ruudk avatar Sep 17 '24 17:09 ruudk

Not as easy as it looks.

See

  • https://github.com/phpstan/phpstan-doctrine/pull/520
  • https://github.com/phpstan/phpstan-doctrine/pull/588
  • Also https://github.com/phpstan/phpstan-doctrine/pull/592

VincentLanglet avatar Nov 07 '24 21:11 VincentLanglet

I'd recommend using https://github.com/staabm/phpstan-dba additionally which resolves types much narrower for most queries.

Seldaek avatar Nov 27 '24 08:11 Seldaek