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

Larastan Strict Rules Laravel Package

canvural/larastan-strict-rules

Extra strict, opinionated PHPStan rules for Laravel via Larastan. Enforce safer patterns by banning dynamic where methods, facades, and global helpers; prevent validation in controllers; ensure scopes return Eloquent Builder. Enable all at once or toggle rules individually.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require --dev canvural/larastan-strict-rules
    
  2. Configure PHPStan (phpstan.neon):
    includes:
        - vendor/canvural/larastan-strict-rules/rules.neon
    
  3. Run PHPStan:
    vendor/bin/phpstan analyse
    

First Use Case

Start with NoFacadeRule to enforce dependency injection over facades:

// Before (flagged)
$users = User::all();

// After (recommended)
$users = app(User::class)->all();

Implementation Patterns

Gradual Adoption

  1. Enable rules incrementally by disabling allRules and enabling specific rules:
    parameters:
        larastanStrictRules:
            allRules: false
            noFacade: true
            noGlobalLaravelFunction: true
    
  2. Test in CI first to catch violations early.

Common Workflows

  • Facade Replacement: Replace Route::get() with dependency-injected Router:
    // Before
    Route::get('/users', [UserController::class, 'index']);
    
    // After (in routes file)
    $router->get('/users', [UserController::class, 'index']);
    
  • Validation in Controllers: Move validation to Form Requests (app/Http/Requests/StoreUserRequest):
    public function rules(): array {
        return ['email' => 'required|email'];
    }
    
    Controller becomes:
    public function store(StoreUserRequest $request) {
        // No manual validation needed
    }
    

Integration Tips

  • Pair with phpstan-soft for gradual enforcement:
    level: 8
    strictness: soft
    
  • Use allowedGlobalFunctions for exceptions (e.g., auth()):
    parameters:
        allowedGlobalFunctions:
            - auth
    

Gotchas and Tips

Pitfalls

  1. False Positives in NoDynamicWhereRule:

    • Model scopes (e.g., User::published()) may trigger this rule. Exclude them via:
      parameters:
          larastanStrictRules:
              noDynamicWhere: false
      
    • Or update scopes to return Builder explicitly:
      public function scopePublished($query) {
          return $query->where('published', true);
      }
      
  2. Listener Paths Misconfiguration:

    • Forgetting to set listenerPaths for ListenerShouldHaveVoidReturnTypeRule will silently ignore the rule.
    • Example:
      parameters:
          listenerPaths:
              - app/Listeners
              - app/Events
      
  3. Property Accessors:

    • The NoPropertyAccessorRule blocks both definition and usage:
      // Both flagged:
      protected $attributes = ['name' => 'Can'];
      
      public function getNameAttribute() { ... }
      

Debugging

  • Rule-Specific Errors:
    • Use --error-format=github for clear PR feedback:
      vendor/bin/phpstan analyse --error-format=github
      
  • Disable All Rules Temporarily:
    parameters:
        larastanStrictRules:
            allRules: false
    

Extension Points

  1. Custom Rules: Extend the package by creating a custom Rule class (e.g., NoHardcodedRoutesRule) and include it in rules.neon:

    includes:
        - vendor/canvural/larastan-strict-rules/rules.neon
        - app/Rules/CustomRule.neon
    
  2. Override Rule Logic: Fork the package and modify NoFacadeRule to allow specific facades (e.g., Cache::remember()).

Performance

  • Cache PHPStan Results: Add to phpstan.neon:
    scanFileInfo: false
    

Laravel-Specific Quirks

  • Testbench Compatibility: Ensure orchestra/testbench is updated (see changelog).
  • Dynamic Method Calls: The NoDynamicWhereRule may conflict with dynamic methods like whereHas() or with(). Exclude them via:
    parameters:
        larastanStrictRules:
            noDynamicWhere: false
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor