Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phpstan Doctrine Laravel Package

phpstan/phpstan-doctrine

PHPStan extension for Doctrine that validates DQL and QueryBuilder, checks repository findBy and magic methods, improves EntityManager and repository type inference, supports ORM and ODM, and reports mapping, entity type, and proxy issues.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for data-layer static analysis. Adopting this extension is effectively a "buy" decision at zero license cost (MIT) versus writing and maintaining in-house PHPStan rules and Doctrine stubs. It is a dev-only Composer dependency with no runtime footprint, so the decision is cheap and reversible.
  • Whether to fund a type-safety / PHPStan level-up initiative. On Doctrine-heavy codebases, raising PHPStan levels is impractical without Doctrine awareness: getRepository(), magic findBy* methods, and DQL results otherwise degrade to mixed and generate noise. This package provides the type inference that makes a level upgrade a tractable roadmap item rather than an open-ended cleanup.
  • Scope of the CI quality gate. DQL validation (parse errors, unknown entities, unknown persistent fields), QueryBuilder validation, and field checks on findBy*/findOneBy*/countBy* move a class of data-access bugs from production 500s into pre-merge failures. That supports a decision to treat CI as the primary correctness gate for query construction.
  • Security roadmap input. The opt-in doctrine.literalString setting types DBAL parameters (e.g. Connection::executeQuery($sql)) as literal-string, so interpolated user input is flagged statically. This is a concrete, low-cost control to cite in secure-coding standards and audit responses.
  • Engineering standards and repository API guidelines. Query type inference degrades when QueryBuilders are passed across method boundaries or built with dynamic expressions. That is evidence for codifying conventions (DQL confined to repositories, no QueryBuilder parameters, static select/from/join), and reportDynamicQueryBuilders: true turns the convention into an enforceable signal.
  • ORM/Symfony upgrade planning. Detection of final entity classes and final constructors that break Doctrine proxy generation, plus mapping configuration errors, directly de-risks Doctrine upgrades and a migration to native lazy objects. Precise throw types for EntityManager::flush() also improve error-handling design around uniqueness violations.
  • Tech-debt and dead-code programs. Entity properties are excluded from unused-property reports, and Gedmo-managed fields (Timestampable, Blameable, Slug), generated identifiers, and version fields are recognized. This keeps a cleanup initiative from drowning in false positives on the domain model.
  • Test strategy tradeoffs. DQL analysis is static and needs no running database, so the team can decide how much integration-test coverage of query construction is redundant versus still necessary for hydration and driver behavior. It complements tests; it does not replace them.
  • Prioritizing custom-type work. reportUnknownTypes: true converts "we have some custom DBAL types" into an explicit checklist, letting you size descriptor work (or lean on ReflectionDescriptor) before committing to full analysis coverage.

When to Consider This Package

Good fit:

  • Doctrine ORM or ODM is a core part of the stack (Symfony or standalone), with entities and repositories representing meaningful surface area.
  • PHPStan is already in CI, or a static-analysis initiative is approved and funded; the extension only pays off through PHPStan.
  • The team can own a small but real artifact: the objectManagerLoader bootstrap (kernel boot, env loading, container lookup), including per-kernel variants in multi-app monorepos.
  • There is appetite to triage an initial baseline and to add descriptors for custom DBAL types when reportUnknownTypes flags them.
  • Leading indicators: recurring "unknown field" or invalid-DQL errors, a Doctrine major upgrade on the roadmap, or an explicit strict-typing goal.

Look elsewhere or defer:

  • No Doctrine (Eloquent, raw PDO, Cycle, or query-builder-only data layers) — the package has nothing to analyze.
  • No static-analysis practice and no appetite to start one; the value accrues entirely through PHPStan adoption.
  • Heavily dynamic query construction. DQL rules still help, but type inference benefits shrink, and subqueries currently infer as mixed.
  • Very small or frozen codebases where entity churn is minimal and CI minutes are contested.
  • Anyone expecting runtime guarantees. This does not replace integration tests, migration checks, or database-level constraints.
  • Version-pinning constraints: confirm compatibility with your PHPStan major, and note that some Query methods only resolve types when Query::HYDRATE_OBJECT is passed explicitly.

How to Pitch It (Stakeholders)

For executives. A free, MIT-licensed, development-only Composer dependency, published under the official phpstan/ organization with a steady release cadence (2.0.x line, active maintenance). It converts a recurring category of production incidents — misspelled fields in repository findBy* calls, malformed or referencing-nonexistent-field DQL, Doctrine mapping mistakes, and proxy failures from final entities — into build-time errors. There is no runtime footprint, no license cost, and no vendor lock-in: adoption is one dev dependency plus a config include, and rollback is deleting a line from phpstan.neon. Setup and initial triage is on the order of days, not a quarter.

For engineering. Value arrives in stages: install the extension for immediate type inference (EntityManager::getRepository(), find, getReference, magic findBy*/countBy*, EntityRepository<T> generics, Collection::first()/last() narrowing); then add rules.neon plus an objectManagerLoader to unlock DQL validation and full query result-type inference (including driver-aware expression types for MySQL, SQLite, and PostgreSQL setups). From there, opt into literalString for injection-risk detection, reportUnknownTypes to close custom-type coverage gaps, and reportDynamicQueryBuilders to surface code that static analysis cannot reason about. Custom DQL functions that implement TypedExpression are inferred correctly; others fall back to mixed.

What to measure. DQL and repository-field errors caught pre-merge, PHPStan level achieved, reduction in data-layer runtime exceptions, and time-to-diagnose during ORM upgrades. Risks to name up front: an initial baseline of findings, ongoing ownership of the object-manager bootstrap, occasional false positives around proxy-sensitive final classes (relaxable, and moot once native lazy objects are enabled), and the need to author descriptors for custom DBAL types.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
teamzac/geocoder
ideatica/config-writer
keaton-php/pipe-dream
jacksonwebservices/laravel-user-suite
maksimru/conditional-laravel-debugbar
gismatul/nova-support-chat
gismatul/laravel-support-chat
networkrailbusinesssystems/oracle-api
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
ably/pubsub-server
mstfkhazaal/defender
mfonte/base62x
karnoweb/metapilot
tobya/bcsapiwrapper
swalker2/cpanel