Weave Code
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 Strict Rules Laravel Package

phpstan/phpstan-strict-rules

Opinionated extra rules for PHPStan to enforce strict, strongly typed PHP. Catches loose booleans in conditions, unsafe strict parameters, useless casts, non-numeric arithmetic, variable overwrites in loops, and switch/case type mismatches for safer defensive code.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev phpstan/phpstan-strict-rules
    

    Use phpstan/extension-installer for automatic inclusion in your phpstan.neon config.

  2. First Run: Execute PHPStan with the default strict rules:

    vendor/bin/phpstan analyse src --level=max
    

    The package enforces stricter defaults (e.g., checkStrictPrintfPlaceholderTypes=true).

  3. First Use Case: Run PHPStan on a Laravel controller to catch common pitfalls like:

    • Loose comparisons (==/!=).
    • Implicit array creation ($var[] =).
    • Backtick operator usage (e.g., shell commands).

Implementation Patterns

Workflows

  1. Gradual Adoption: Disable all rules initially (strictRules.allRules: false), then enable them incrementally:

    parameters:
        strictRules:
            disallowedLooseComparison: true
            booleansInConditions: true
    
  2. Team Onboarding:

    • Use phpstan/extension-installer to auto-include rules in CI/CD pipelines.
    • Document exceptions in phpstan.neon:
      ignoreErrors:
          - '#DisallowedLooseComparison# in app/Helpers/legacy.php'
      
  3. Laravel-Specific Patterns:

    • Service Containers: Enforce strictFunctionCalls for array_key_exists() in dependency injection.
    • Eloquent Models: Use matchingInheritedMethodNames to catch case-sensitive method overrides.
    • Middleware: Apply closureUsesThis to ensure closures reference $this directly.
  4. Testing:

    • Integrate with phpunit/phpstan to fail builds on strict rule violations.
    • Example GitHub Actions workflow:
      - name: PHPStan Strict Rules
        run: vendor/bin/phpstan analyse --level=max
      

Integration Tips

  • Custom Rules: Extend existing rules by subclassing PhpStan\StrictRules\Rules\* and override processNode().
  • Laravel Facades: Disable dynamicCallOnStaticMethod for facades (e.g., Cache::remember()) via:
    ignoreErrors:
        - '#DynamicCallOnStaticMethod# in app/Providers/AppServiceProvider.php'
    
  • Legacy Code: Use @phpstan-ignore-next-line sparingly for legacy helpers.

Gotchas and Tips

Pitfalls

  1. False Positives:

    • UselessCast: May flag (void) casts on #[\NoDiscard] methods (fixed in v2.0.11).
    • disallowedEmpty: Conflicts with Laravel’s Arr::exists() helper. Exclude:
      ignoreErrors:
          - '#DisallowedEmpty# in vendor/laravel/framework/src/Illuminate/Support/Arr.php'
      
  2. Performance:

    • Rules like checkAlwaysTrueStrictComparison add overhead. Disable if CI timeouts occur:
      parameters:
          strictRules:
              checkAlwaysTrueStrictComparison: false
      
  3. Laravel-Specific Issues:

    • Service Providers: requireParentConstructorCall may conflict with Laravel’s BootServiceProvider. Exclude:
      ignoreErrors:
          - '#RequireParentConstructorCall# in app/Providers/BootServiceProvider.php'
      
    • Blade Templates: Rules like disallowedShortTernary may trigger in @php directives. Use:
      @php($value ?? null) // Instead of $value ?: null
      

Debugging

  • Verbose Output: Run with --verbose to see rule-specific messages:
    vendor/bin/phpstan analyse --verbose
    
  • Rule-Specific Help: Check the PHPStan docs for each parameter (e.g., numericOperandsInArithmeticOperators).

Extension Points

  1. Custom Rules: Create a Rules directory in your project and extend PhpStan\StrictRules\Rules\BaseRule:

    namespace App\Rules;
    use PhpStan\StrictRules\Rules\BaseRule;
    
    class CustomRule extends BaseRule {
        public function processNode(Node $node) { ... }
    }
    

    Include in phpstan.neon:

    includes:
        - app/Rules/*.php
    
  2. Overriding Defaults: Override PHPStan’s core parameters in phpstan.neon:

    parameters:
        checkStrictPrintfPlaceholderTypes: true
        reportNonIntStringArrayKey: true
    
  3. Selective Enforcement: Use @phpstan-ignore-line for specific lines or @phpstan-ignore-file for entire files (e.g., third-party libraries).

Pro Tips

  • Pair with phpstan/phpstan-doctrine: Enforce strict typing in Laravel’s Doctrine entities.
  • Combine with phpstan/phpstan-phpunit: Catch type mismatches in test assertions.
  • CI/CD Optimization: Cache PHPStan results between runs:
    vendor/bin/phpstan analyse --generate-baseline
    
    Commit the baseline and re-run with --baseline to only show new issues.

```markdown
### Laravel-Specific Quirks
1. **Facade Calls**:
   Disable `dynamicCallOnStaticMethod` for Laravel facades (e.g., `Auth::user()`):
   ```neon
   ignoreErrors:
       - '#DynamicCallOnStaticMethod# in app/Http/Controllers/AuthController.php'
  1. Artisan Commands: Rules like disallowedBacktick may conflict with Artisan::call(). Exclude:

    ignoreErrors:
        - '#DisallowedBacktick# in app/Console/Commands/DeployCommand.php'
    
  2. Service Container: Use strictFunctionCalls to enforce $strict=true in array_key_exists() calls within service bindings:

    $this->app->bind('key', function () {
        return array_key_exists('key', $array, true); // Enforced by strictRules
    });
    
  3. Migration Files: Disable disallowedLooseComparison for legacy migrations:

    ignoreErrors:
        - '#DisallowedLooseComparison# in database/migrations/2020_*.php'
    
  4. Event Listeners: Apply closureUsesThis to ensure closures in listeners reference $this directly:

    Event::listen('event', function () {
        $this->someMethod(); // Direct $this usage (enforced)
    });
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope