The Case for Strict PHPStan Baselines in Enterprise Codebases

Published: (March 8, 2026 at 08:17 AM EDT)
2 min read
Source: Dev.to

Source: Dev.to

Problem

Modernizing a legacy PHP application presents a paradox: you critically need strict static analysis to prevent future bugs, but turning on a tool like PHPStan immediately throws thousands of errors, completely breaking the CI pipeline.

During a recent stabilization project on an enterprise platform (rlh‑core), the codebase had excellent business logic but was rife with missing return types, loose array definitions, and checks like empty($message) instead of strict null checks.
A naive approach would be to halt feature development for a month and force the team to fix all existing errors until PHPStan returns green—an approach that is financially unsustainable.
Leaving PHPStan disabled, however, allows technical debt to accumulate unchecked.

Solution: PHPStan Baseline Pattern

  1. Configure PHPStan at maximum strictness (Level 8).

  2. Run it against the entire codebase and pipe the output into a baseline file:

    vendor/bin/phpstan analyse -c phpstan.neon --error-format=raw > phpstan-baseline.neon

    The generated phpstan-baseline.neon acts as a cryptographic signature of the existing technical debt, telling the CI pipeline to ignore those specific errors on the identified lines.

  3. Commit the baseline. The CI pipeline now passes (green) while the strict Level 8 rules are active for all new code.

  4. Enforce a baseline rule: when a file is touched for a new feature, any baseline errors in that file must be resolved.

  5. Automatic cleanup: when an engineer fixes an issue (e.g., replaces empty() with a strict null check), PHPStan detects that the error no longer exists and prompts the removal of the corresponding entry from the baseline (reportUnmatched: true).

Results

  • Over six months, the baseline shrank from ~5,000 errors to under 300 without a dedicated refactoring sprint.
  • New code that violates strict rules (missing return types, unchecked array keys, etc.) fails the build, preventing the introduction of additional debt.
  • The application became highly deterministic and type‑safe by enforcing a strict boundary on new code while gradually reducing legacy issues.

Takeaway

When dealing with enterprise technical debt, the strategy isn’t to “burn the house down”; it’s to stop adding fuel to the fire by enforcing strict static analysis for all new development while systematically eliminating existing problems.

Originally published at VictorStack AI — Drupal & WordPress Reference.

0 views
Back to Blog

Related posts

Read more »