Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phpstan Rules Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Add the package via Composer:

    composer require --dev shipmonk/phpstan-rules
    
  2. Enable Rules Include the rules in your phpstan.neon:

    includes:
        - vendor/shipmonk/phpstan-rules/rules.neon
    
  3. 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).


Where to Look First

  • Rule Documentation: Review the Rules section in the README to identify which rules align with your project’s needs.
  • Configuration: Check the Configuration section for how to enable/disable specific rules.
  • Common Pitfalls: Start with rules like forbidCast and enforceNativeReturnTypehint, as they catch common anti-patterns.

Implementation Patterns

Workflows

  1. Incremental Adoption

    • Enable rules in batches (e.g., start with enforceReadonlyPublicProperty and forbidCast).
    • Use enableAllRules: false to selectively enable rules:
      parameters:
          shipmonkRules:
              enableAllRules: false
              enforceReadonlyPublicProperty:
                  enabled: true
      
  2. Integration with CI

    • Add PHPStan to your CI pipeline with the new rules:
      # .github/workflows/phpstan.yml
      - run: vendor/bin/phpstan analyse --level=max src
      
  3. Custom Rule Configuration

    • Override defaults for specific rules (e.g., allow numeric strings in forbidArithmeticOperationOnNonNumber):
      parameters:
          shipmonkRules:
              forbidArithmeticOperationOnNonNumber:
                  allowNumericString: true
      

Integration Tips

  • 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
    

Gotchas and Tips

Pitfalls

  1. Rule Overlap with Native PHPStan

    • Some rules (e.g., 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.
  2. Performance Impact

    • Rules like forbidCheckedExceptionInCallable add significant analysis overhead. Run PHPStan in CI with --memory-limit=2G if needed.
  3. 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
      
  4. Configuration Merging

    • PHPStan merges configs by default. Use ! to override defaults:
      parameters:
          shipmonkRules:
              forbidCast:
                  blacklist!: ['(array)'] # Overrides all defaults
      

Debugging

  • 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
    

Tips

  1. Start with forbidCast This rule catches common anti-patterns like (array) $var and (object) $var early.

  2. 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> { ... }
    
  3. Use classSuffixNaming for Consistency Enforce naming conventions (e.g., *Test for tests):

    parameters:
        shipmonkRules:
            classSuffixNaming:
                superclassToSuffixMapping!:
                    \PHPUnit\Framework\TestCase: Test
    
  4. 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);
    
  5. 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) { ... }
    
  6. 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
    
  7. Monitor Rule Effectiveness Track false positives/negatives in a FIXME comment:

    // FIXME: Disable forbidArithmeticOperationOnNonNumber for this case
    $result = (string) $value + 1; // Allowed via config
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style