PHPackages                             stesie/phpstan-doctrine-checker - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. stesie/phpstan-doctrine-checker

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

stesie/phpstan-doctrine-checker
===============================

PHPStan Doctrine checker to find invalid, filtered fetch-join queries.

110PHP

Since Aug 26Pushed 8y ago2 watchersCompare

[ Source](https://github.com/stesie/phpstan-doctrine-checker)[ Packagist](https://packagist.org/packages/stesie/phpstan-doctrine-checker)[ RSS](/packages/stesie-phpstan-doctrine-checker/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

PHPStan Doctrine (Fetch-Join) Checker
=====================================

[](#phpstan-doctrine-fetch-join-checker)

[![Build Status](https://camo.githubusercontent.com/56852571f86beb15a0ed5e34d8205c90200aa8ef74ea091b12e1a28c29577571/68747470733a2f2f7472617669732d63692e6f72672f7374657369652f7068707374616e2d646f637472696e652d636865636b65722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/stesie/phpstan-doctrine-checker)[![Coverage Status](https://camo.githubusercontent.com/2709b65068bf589a5018c4c91b7c419f3ee7d25ef62272dd5455a69a6a80789f/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f7374657369652f7068707374616e2d646f637472696e652d636865636b65722f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/stesie/phpstan-doctrine-checker?branch=master)[![PHPStan](https://camo.githubusercontent.com/e43e27acff50e6ee0656e0a112d484ff55f844ff10e79b3d17641033ea51d18f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374796c652d6c6576656c253230372d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265266c6162656c3d7068707374616e)](https://camo.githubusercontent.com/e43e27acff50e6ee0656e0a112d484ff55f844ff10e79b3d17641033ea51d18f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7374796c652d6c6576656c253230372d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265266c6162656c3d7068707374616e)[![License](https://camo.githubusercontent.com/8a346f512412392e6440c11992c358e74016de5e3ef5ead7e5933165070b061e/68747470733a2f2f706f7365722e707567782e6f72672f7374657369652f7068707374616e2d646f637472696e652d636865636b65722f6c6963656e7365)](https://packagist.org/packages/stesie/phpstan-doctrine-checker)

PHPStan Doctrine Checker is an extension for [PHPStan](https://github.com/phpstan/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](https://github.com/phpstan/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
-----

[](#usage)

To use this extension, require it with [composer](https://getcomposer.org/):

```
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
-------

[](#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
------------

[](#contributing)

Any contributions are welcome.

###  Health Score

21

—

LowBetter than 19% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/cfbaa82879329d66159d2244629a3554cbd5b62815c3be35c39b591625d3fb08?d=identicon)[stesie](/maintainers/stesie)

---

Top Contributors

[![stesie](https://avatars.githubusercontent.com/u/113068?v=4)](https://github.com/stesie "stesie (35 commits)")

### Embed Badge

![Health badge](/badges/stesie-phpstan-doctrine-checker/health.svg)

```
[![Health](https://phpackages.com/badges/stesie-phpstan-doctrine-checker/health.svg)](https://phpackages.com/packages/stesie-phpstan-doctrine-checker)
```

###  Alternatives

[webmozart/assert

Assertions to validate method input/output with nice error messages.

7.6k894.0M1.2k](/packages/webmozart-assert)[bensampo/laravel-enum

Simple, extensible and powerful enumeration implementation for Laravel.

2.0k15.9M104](/packages/bensampo-laravel-enum)[nette/forms

📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server &amp; client side validation and mature design.

54013.2M450](/packages/nette-forms)[swaggest/json-schema

High definition PHP structures with JSON-schema based validation

48612.5M73](/packages/swaggest-json-schema)[stevebauman/purify

An HTML Purifier / Sanitizer for Laravel

5325.6M19](/packages/stevebauman-purify)[ashallendesign/laravel-config-validator

A package for validating your Laravel app's config.

217905.3k5](/packages/ashallendesign-laravel-config-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
