shipmonk/phpstan-rules
ShipMonk PHPStan strict rules adds about 40 opinionated, super-strict checks beyond native PHPStan, targeting gaps like unsafe comparisons, casts, and array keys. Install via Composer, include rules.neon, and disable or reconfigure any rule per project.
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?