- How do I install symplify/phpstan-rules in a Laravel app?
- Run composer require --dev symplify/phpstan-rules with phpstan/extension-installer already installed, since the package registers its rule sets automatically through extra.phpstan.includes. After that you configure everything with symplify.* parameters in phpstan.neon instead of hand-written vendor include paths. No changes to routing, service providers or Blade templates are needed.
- Do I need phpstan/extension-installer to use symplify/phpstan-rules?
- Yes for the zero-config setup. Auto-registration of the rule sets relies on phpstan/extension-installer, which most Laravel projects already have because phpstan:install adds it. Without it the package loads silently and no rules apply, which is a quiet failure mode. Do a smoke check by intentionally violating a known rule in a scratch file during rollout.
- Why does upgrading to 14.17.0 fail with duplicated includes in phpstan.neon?
- Earlier versions required manual includes such as naming-rules.neon, static-rules.neon or symplify-rules.neon. Since 14.17.0 those sets are auto-registered, so keeping the old includes produces a duplicated-include failure that blocks CI. Remove the manual includes in the same commit as the version bump. Bundling the upgrade and the config cleanup in one pull request keeps the build green.
- Which symplify/phpstan-rules sets are enabled by default?
- The sets closest to common anti-patterns, naming, static, doctrine and symfony, are on by default, while the noisier mocks and ctor sets stay off until you opt in. rector-rules.neon remains opt-in as well. The exact enable and disable matrix is documented in the release notes, and you can pin every symplify.* toggle explicitly so your effective config is auditable.
- How do I disable a rule set or a single rule in symplify/phpstan-rules?
- Flip the matching toggle in parameters.symplify, for example symplify.mocks: false or symplify.ctor: false, and the whole set disappears from analysis. Individual rules are handled the usual PHPStan way with ignoreErrors or custom rule configuration. Typos or stale keys fall back to package defaults, which can silently enable more than you intended, so double-check the key names.
- How do I get return type inference for Laravel's $container->make()?
- The return type extensions are disabled by default. Enable laravelReturnType: true under parameters.symplify and PHPStan resolves $container->make(SomeService::class) to SomeService instead of plain object. symfonyReturnType does the same for Container::get(), and pathStrings narrows getcwd(), dirname() and realpath() to string. Turn on only the extensions that match your stack.
- How do I enable the PHPUnit mock rules such as NoTestMocksRule?
- Set symplify.mocks: true in phpstan.neon parameters. The mocks and ctor sets are off by default because they are noisier, so teams migrating from the old include-based setup will find NoTestMocksRule inactive until they deliberately opt in. Constructor-related rules work the same way through symplify.ctor.
- Are the Symfony and Doctrine rule sets safe to run on a Laravel project?
- They are part of the default-on sets and focus on proven practices rather than framework internals, so most checks apply to Laravel code as well. Expect some framework noise, for example around Mailer transports, which PreferInterfaceInConstructorRule now skips to reduce false positives. Native rules for Illuminate\Contracts, Nova, Fortify, Vapor or Blade do not exist, so custom extensions may still be needed for those areas.
- How do I roll out symplify/phpstan-rules without a flood of new errors?
- Snapshot your current PHPStan error baseline first, then pin every symplify.* toggle to the sets you effectively had before the upgrade. Enable additional sets one at a time and fix or baseline the new findings between steps. Because sets are booleans in a single control plane, incremental adoption needs no neon include edits.
- Is symplify/phpstan-rules maintained, and does it require a specific Laravel version?
- The package is MIT licensed and has no dependency on Laravel internals, so it works across Laravel versions as long as your PHPStan setup is compatible. It is PHPStan-native, composes with your existing level:, paths and excludes, and works with Pest or PHPUnit suites. Check the release notes before each upgrade, since behaviour changes such as new default-on sets are not always labelled as breaking.