shipmonk/phpstan-rules
40 super-strict PHPStan rules from ShipMonk to plug gaps in extra-strict setups. Install via Composer, include rules.neon, then enable/disable or tune rules per-project. Targets tricky PHP edge cases like unsafe comparisons, casts, arrays, enums and more.
Installation Add the package via Composer:
composer require --dev shipmonk/phpstan-rules
Enable Rules
Include the rules in your phpstan.neon:
includes:
- vendor/shipmonk/phpstan-rules/rules.neon
First Use Case Run PHPStan with the new rules:
vendor/bin/phpstan analyse src
Focus on the most critical rules first (e.g., forbidCast, enforceReadonlyPublicProperty).
forbidCast and enforceNativeReturnTypehint, as they catch common anti-patterns.Incremental Adoption
enforceReadonlyPublicProperty and forbidCast).enableAllRules: false to selectively enable rules:
parameters:
shipmonkRules:
enableAllRules: false
enforceReadonlyPublicProperty:
enabled: true
Integration with CI
# .github/workflows/phpstan.yml
- run: vendor/bin/phpstan analyse --level=max src
Custom Rule Configuration
forbidArithmeticOperationOnNonNumber):
parameters:
shipmonkRules:
forbidArithmeticOperationOnNonNumber:
allowNumericString: true
Leverage PHPStan’s Native Rules
Combine with native PHPStan rules (e.g., reportAnyTypeWideningInVarTag) for stricter type safety:
parameters:
reportAnyTypeWideningInVarTag: true
Use with BackedEnum Generics
If using backedEnumGenerics, ensure your phpstan.neon includes the stub file:
parameters:
stubFiles:
- vendor/shipmonk/phpstan-rules/BackedEnum.php.stub
Enforce Closure Type Safety
Pair enforceClosureParamNativeTypehint with PHP 8.0+ for stricter closure analysis:
parameters:
shipmonkRules:
enforceClosureParamNativeTypehint:
allowMissingTypeWhenInferred: false
Rule Overlap with Native PHPStan
enforceEnumMatch) address PHPStan’s historical quirks (e.g., false positives in enum comparisons). Ensure you’re using PHPStan 1.10.34+ to avoid redundant rules.Performance Impact
forbidCheckedExceptionInCallable add significant analysis overhead. Run PHPStan in CI with --memory-limit=2G if needed.False Positives in Generics
backedEnumGenerics requires explicit stub configuration. Without it, the rule does nothing:
# Missing stub = rule silently fails
parameters:
shipmonkRules:
backedEnumGenerics:
enabled: true
Configuration Merging
! to override defaults:
parameters:
shipmonkRules:
forbidCast:
blacklist!: ['(array)'] # Overrides all defaults
Disable Rules Temporarily Isolate issues by disabling specific rules:
parameters:
shipmonkRules:
enforceReadonlyPublicProperty:
enabled: false
Check Rule-Specific Errors PHPStan outputs rule names in errors. Example:
[shipmonk/enforceReadonlyPublicProperty] Property $foo must be readonly
Use --error-format=json
For CI debugging, generate JSON output to parse errors programmatically:
vendor/bin/phpstan analyse --error-format=json src > phpstan-errors.json
Start with forbidCast
This rule catches common anti-patterns like (array) $var and (object) $var early.
Pair with enforceNativeReturnTypehint
Reduces PHPDoc verbosity and improves IDE support:
// Before
/** @return array<int> */
public function getIds(): array { ... }
// After (PHP 8.0+)
public function getIds(): array<int> { ... }
Use classSuffixNaming for Consistency
Enforce naming conventions (e.g., *Test for tests):
parameters:
shipmonkRules:
classSuffixNaming:
superclassToSuffixMapping!:
\PHPUnit\Framework\TestCase: Test
Leverage enforceIteratorToArrayPreserveKeys
Avoid silent data loss in iterator_to_array() calls:
// Bad (default preserve_keys=true)
iterator_to_array($generator);
// Good (explicit)
iterator_to_array($generator, preserveKeys: false);
Combine with forbidCheckedExceptionInCallable
Prevent silent exceptions in closures/arrow functions:
// Bad (throws checked exception)
$callback = fn() => $this->userRepository->find($id);
// Good (explicit handling)
try {
$callback();
} catch (UserNotFoundException $e) { ... }
Extend Rules via Custom Config
Add project-specific rules by extending the rules.neon file:
# custom-rules.neon
parameters:
shipmonkRules:
forbidCustomFunctions:
blacklist:
- \YourApp\Legacy\deprecatedMethod
Monitor Rule Effectiveness
Track false positives/negatives in a FIXME comment:
// FIXME: Disable forbidArithmeticOperationOnNonNumber for this case
$result = (string) $value + 1; // Allowed via config
How can I help you explore Laravel packages today?