stesie / phpstan-doctrine-checker
PHPStan Doctrine checker to find invalid, filtered fetch-join queries.
Requires
- doctrine/orm: ^2.5
- phpstan/phpstan: ^0.8.0
Requires (Dev)
- consistence/coding-standard: ^2.0
- jakub-onderka/php-console-highlighter: ^0.3.2
- jakub-onderka/php-parallel-lint: ^0.9.2
- phpunit/phpunit: ^6.0.3
- satooshi/php-coveralls: ^1.0
- slevomat/coding-standard: ^3.0
- squizlabs/php_codesniffer: ^3.0
This package is not auto-updated.
Last update: 2024-10-27 04:43:45 UTC
README
PHPStan Doctrine Checker is an extension for PHPStan, that provides extra checks for PHPStan.
This project wouldn't be possible without the wonderful PHPStan tool. If you consider using this extension, you really also should add the phpstan-doctrine extension.
So far this is just a proof of concept and not really usable
The foremost goal is to find uses of Doctrine's QueryBuilder to construct (invalid) fetch-join queries over filtered associations. The problem with these is that they easily go undetected and blow off at a totally different point in your code.
Consider this:
$user = $this->_em->createQueryBuilder() ->select('u', 'p') ->from(User::class, 'u') ->join('u.phoneNumbers', 'p') ->where('p.type = :type')->setParameter('type', 'work') ->getQuery() ->getResult();
Here the associated phoneNumbers
are fetch-joined and also filtered. If this query is executed
another time, maybe for all numbers with type "home", then Doctrine will not re-hydrate the
already hydrated User
entities, and hence those will still have the work phone-number attached.
Usage
To use this extension, require it with composer:
composer require --dev stesie/phpstan-doctrine-checker=@dev
And include src/phpstan.neon
in your project's PHPStan config:
includes:
- vendor/stesie/phpstan-doctrine-checker/src/phpstan.neon
Roadmap
So far this project is more a proof of concept, less really usable.
Stuff I would really like to see implemented
- handle all
getResult
variants that hydrate to objects (and ignore the rest) - more robust interpreting of various
$qb->expr()->xxx
filtering - don't warn on filtering on (non-nullable?)
xxxToOne
relations, as those should eliminate the root (and hence not lead to partly hydrated objects) - back-propagate filtering done on inner join'ed related tables, i.e. if you fetch join foo and bar tables, but baz (which depends on bar) is filtered ... then if baz is filtered out, it'll eliminate bar and (maybe) only partly hydrate foo.
- parse raw DQL
Contributing
Any contributions are welcome.