soyhuce/phpstan-extension
A PHPStan extension from Soyhuce that adds custom rules and type extensions for Laravel and PHP projects, helping teams catch bugs earlier and improve static analysis accuracy in CI and local development.
soyhuce/phpstan-extension is a dev-only PHPStan extension, so treat it as part of your static-analysis toolchain rather than an application dependency.
Install it alongside PHPStan itself:
composer require --dev phpstan/phpstan soyhuce/phpstan-extension
Both entries belong in require-dev; nothing should resolve at runtime.
Confirm the installed version supports your stack. Release 2.1.0 added Laravel 12 test coverage, so Laravel 10/11/12 are all reasonable targets. If you are still on Laravel 10 or 11, no action is needed beyond a normal composer update — the release carries no configuration or API changes.
Register the extension in phpstan.neon.dist (commit this file; keep machine-specific tweaks in a gitignored phpstan.neon):
includes:
- vendor/soyhuce/phpstan-extension/extension.neon
The exact relative-path include is the part people get wrong most often — check the package README for the shipped .neon filename in your version before copying examples from blog posts.
First run:
vendor/bin/phpstan analyse --memory-limit=1G
First use case: if you are retrofitting this into an existing Laravel app, do not start at level 8. Run once with --level=5 (or whatever your current level is), accept the noise, and immediately generate a baseline:
vendor/bin/phpstan analyse --generate-baseline
That gives you a green build on day one and lets new code be held to the new rules while legacy code is paid down incrementally.
Incremental rule adoption. Add the extension's ruleset, then suppress individual rules you are not ready for via ignoreErrors with path/identifier keys rather than lowering the overall level. Identifiers (PHPStan 1.11+) survive refactors far better than message-text matching.
Scoped analysis paths. Most Laravel projects want app/, config/, database/, routes/ in paths, but not tests/ or storage/. Run a second, looser config over tests/ if you want coverage there — mixing them forces you to relax rules that matter in production code.
CI integration. Run PHPStan as its own job with the result cache persisted between builds:
- run: vendor/bin/phpstan analyse --no-progress --error-format=github
The github error format annotates the diff inline, which is where this package earns its keep in day-to-day review work. Cache the tmpDir (default /tmp/phpstan) keyed on composer.lock plus a hash of the source tree.
Pairing with Pint and Laravel-specific tooling. This package covers type-level and structural correctness; it is not a style linter. Run it in the same pre-push hook as Pint so a single composer check command covers both — developers stop running whichever one is awkward to invoke.
Editor feedback loop. Point the PHPStan language-server/intellij plugin at the same phpstan.neon.dist. Because this extension ships rules that are Laravel-aware, you get the diagnostics inline while writing a controller, rather than discovering them in CI twenty minutes later.
Local escape hatch. For the one rule that fights you in a specific context, prefer an inline @phpstan-ignore <identifier> with a trailing comment explaining why, over a global suppression. It keeps the inventory of exceptions greppable.
phpstan/phpstan ^1.x vs ^2.x have different config keys), so pin the extension loosely and let Composer solve, then verify with vendor/bin/phpstan --version.checkMissingIterableValueType were removed in PHPStan 2.x. If you copy an older phpstan.neon from another project, you will get "Unexpected item" errors that look like they come from this extension but are actually your own config.--memory-limit=2G. On CI, cap parallel: maximumNumberOfProcesses below the runner's core count; over-subscription is the usual cause of nondeterministic "job killed" failures.vendor/bin/phpstan clear-result-cache before debugging anything else.vendor/ or auto-discovery-generated files produces thousands of unfixable errors and trains the team to ignore PHPStan output entirely..neon rather than forking this package — the fork becomes a maintenance liability the moment the next Laravel or PHPStan release lands.composer update soyhuce/phpstan-extension then re-run analysis with -v; if the reported rule count is unchanged, the release is a no-op for your codebase and you can ship it without a migration plan.How can I help you explore Laravel packages today?