shipmonk/phpstan-rules
40 super-strict PHPStan rules from ShipMonk to close gaps even in extra-strict setups. Installs as an extension, configurable per rule (enable/disable, tweak defaults), with options like safer comparisons, enum generics checks, and more.
laravel/pint, laravel/valet, or custom CI pipelines) without disrupting core functionality.readonly, match expressions). The granular configuration (e.g., disabling specific rules) ensures flexibility for legacy or edge-case Laravel modules.forbidCheckedExceptionInCallable and enforceEnumMatch address common Laravel anti-patterns (e.g., unchecked exceptions in closures, verbose enum handling), reducing runtime bugs in event listeners, service containers, or Eloquent callbacks.shipmonk/phpstan-rules is a dev-only package).phpstan.neon (or custom config) can be extended with minimal changes. Example:
includes:
- vendor/shipmonk/phpstan-rules/rules.neon
parameters:
shipmonkRules:
enforceReadonlyPublicProperty: true
forbidCast:
blacklist!: ['(array)', '(object)']
phpstan:analyze script).enforceNativeReturnTypehint or enforceReadonlyPublicProperty gracefully degrade for PHP <8.0/8.2 (via ignoreErrors or version checks).forbidCheckedExceptionInCallable rule can whitelist Laravel’s checked exceptions (e.g., Illuminate\Database\QueryException) via config.allowComparingOnlyComparableTypes may flag legitimate Laravel patterns (e.g., comparing Carbon instances or Collection keys). Mitigation: Test against Laravel’s core codebase or disable selectively.phpstan analyze --memory-limit=1G --generate-report).enforceEnumMatch) target PHPStan 1.10.x quirks. Ensure compatibility with Laravel’s PHPStan version (e.g., phpstan/phpstan:^1.10 in composer.json).match handling).forbidCustomFunctions may conflict with Laravel’s dynamic methods (e.g., __call, magic getters). Pre-validate against Laravel’s illuminate/support package.enforceReadonlyPublicProperty in new Laravel 10+ modules.enforceNativeReturnTypehint? Plan for phased enforcement.forbidCheckedExceptionInCallable (critical for event listeners).enforceReadonlyPublicProperty (aligns with Laravel’s shift to immutability).forbidCast (reduces array/object casts in Eloquent).forbidCheckedExceptionInCallable?match expressions vs. if-else for enums.laravel-phpstan-rules)?phpstan/phpstan (core analyzer).phpstan/extension-installer (for Composer-based setup).phpstan.neon (or custom config).pint --test to validate code before PHPStan runs.pre-commit or pre-push hooks via husky/laravel-git.forbidArithmeticOperationOnNonNumber may conflict with dynamic SQL (e.g., DB::raw). Whitelist Illuminate\Database\Query\Expression.forbidCheckedExceptionInCallable should whitelist Laravel’s Closure bindings (e.g., App\Providers\AppServiceProvider::boot()).resources/views from analysis unless using @php blocks.auth or api).enforceNativeReturnTypehint (PHP 8.0+).forbidCast (blacklist array/object).enforceReadonlyPublicProperty (PHP 8.2+).composer require --dev shipmonk/phpstan-rules
./vendor/bin/phpstan analyze --config=phpstan.neon
enforceEnumMatch or forbidCheckedExceptionInCallable.- name: PHPStan
run: phpstan analyze --level=max --error-format=github
Illuminate\Validation\ValidationException).CONTRIBUTING.md section on PHPStan rules for new devs.--fix where possible (e.g., adding readonly).| Rule | Laravel 7.x | Laravel 8.x | Laravel 9.x | Laravel 10.x |
|---|---|---|---|---|
enforceNativeReturnTypehint |
❌ (PHP 7.4) | ✅ (PHP 8.0) | ✅ | ✅ |
enforceReadonlyPublicProperty |
❌ (PHP 8.0) | ❌ | ❌ | ✅ (PHP 8.2) |
forbidCheckedExceptionInCallable |
✅ | ✅ | ✅ | ✅ |
^1.10 (Laravel’s default). Upgrade if rules break (e.g., enforceEnumMatch may become redundant post-PHPStan 1.10.34).spatie/laravel-phpstan-stubs (for framework stubs).nunomaduro/collision (if using custom exceptions).ignoreErrors to exclude legacyHow can I help you explore Laravel packages today?