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 Rules Laravel Package

shipmonk/phpstan-rules

40 super-strict PHPStan rules from ShipMonk to close gaps even in extra-strict setups. Installs as an extension, configurable per rule (enable/disable, tweak defaults), with options like safer comparisons, enum generics checks, and more.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Highly Complementary to Laravel/PHP Ecosystem: The package aligns perfectly with Laravel’s PHP-centric architecture, particularly for teams leveraging PHPStan for static analysis. It extends Laravel’s existing tooling (e.g., PHPStan integration in laravel/pint, laravel/valet, or custom CI pipelines) without disrupting core functionality.
  • Opinionated but Configurable: The rules enforce strict coding standards (e.g., immutability, type safety, exception handling) that align with Laravel’s evolving best practices (e.g., PHP 8.2+ features like readonly, match expressions). The granular configuration (e.g., disabling specific rules) ensures flexibility for legacy or edge-case Laravel modules.
  • Focus on Critical Pain Points: Rules like forbidCheckedExceptionInCallable and enforceEnumMatch address common Laravel anti-patterns (e.g., unchecked exceptions in closures, verbose enum handling), reducing runtime bugs in event listeners, service containers, or Eloquent callbacks.

Integration Feasibility

  • Low Friction for Laravel Projects:
    • Composer Integration: Zero dependencies beyond PHPStan (shipmonk/phpstan-rules is a dev-only package).
    • Neon Configuration: Laravel’s phpstan.neon (or custom config) can be extended with minimal changes. Example:
      includes:
          - vendor/shipmonk/phpstan-rules/rules.neon
      parameters:
          shipmonkRules:
              enforceReadonlyPublicProperty: true
              forbidCast:
                  blacklist!: ['(array)', '(object)']
      
    • CI/CD Readiness: Works seamlessly with Laravel’s GitHub Actions, GitLab CI, or custom pipelines (e.g., phpstan:analyze script).
  • Backward Compatibility:
    • PHP Version Guardrails: Rules like enforceNativeReturnTypehint or enforceReadonlyPublicProperty gracefully degrade for PHP <8.0/8.2 (via ignoreErrors or version checks).
    • Laravel-Specific Exceptions: The forbidCheckedExceptionInCallable rule can whitelist Laravel’s checked exceptions (e.g., Illuminate\Database\QueryException) via config.

Technical Risk

  • Rule Overhead:
    • False Positives: Rules like allowComparingOnlyComparableTypes may flag legitimate Laravel patterns (e.g., comparing Carbon instances or Collection keys). Mitigation: Test against Laravel’s core codebase or disable selectively.
    • Performance Impact: PHPStan’s analysis time increases with stricter rules. Benchmark with Laravel’s monorepo (e.g., phpstan analyze --memory-limit=1G --generate-report).
  • Dependency on PHPStan Version:
    • Some rules (e.g., enforceEnumMatch) target PHPStan 1.10.x quirks. Ensure compatibility with Laravel’s PHPStan version (e.g., phpstan/phpstan:^1.10 in composer.json).
    • Future-Proofing: Monitor PHPStan’s roadmap for rule deprecations (e.g., if PHPStan fixes match handling).
  • Custom Laravel Logic:
    • Rules like forbidCustomFunctions may conflict with Laravel’s dynamic methods (e.g., __call, magic getters). Pre-validate against Laravel’s illuminate/support package.

Key Questions for TPM

  1. Adoption Scope:
    • Should this be enforced globally (all repos) or opt-in (feature teams)? Example: Start with enforceReadonlyPublicProperty in new Laravel 10+ modules.
    • How will legacy Laravel 7/8 code handle rules like enforceNativeReturnTypehint? Plan for phased enforcement.
  2. Rule Prioritization:
    • Which 3–5 rules offer the highest ROI for Laravel’s pain points? Example:
      • forbidCheckedExceptionInCallable (critical for event listeners).
      • enforceReadonlyPublicProperty (aligns with Laravel’s shift to immutability).
      • forbidCast (reduces array/object casts in Eloquent).
  3. Tooling Integration:
    • Should this integrate with Laravel Forge/Envoyer for deployment checks?
    • Can it be tied to Laravel IDE Helper for real-time feedback in PHPStorm/VSCode?
  4. Maintenance:
    • Who owns rule updates (e.g., when PHPStan fixes a rule’s target behavior)?
    • How will custom Laravel exceptions be whitelisted in forbidCheckedExceptionInCallable?
  5. Onboarding:
    • What developer training is needed? Example: Workshop on match expressions vs. if-else for enums.
    • Should a custom Laravel rule subset be created (e.g., laravel-phpstan-rules)?

Integration Approach

Stack Fit

  • PHPStan Ecosystem:
    • Native Integration: The package is a PHPStan extension, requiring no Laravel-specific modifications. It works alongside:
      • phpstan/phpstan (core analyzer).
      • phpstan/extension-installer (for Composer-based setup).
      • Laravel’s phpstan.neon (or custom config).
    • Tooling Synergy:
      • Laravel Pint: Use pint --test to validate code before PHPStan runs.
      • Laravel Telescope: Log PHPStan violations as events for debugging.
      • Git Hooks: Integrate with pre-commit or pre-push hooks via husky/laravel-git.
  • Laravel-Specific Considerations:
    • Eloquent/Query Builder: Rules like forbidArithmeticOperationOnNonNumber may conflict with dynamic SQL (e.g., DB::raw). Whitelist Illuminate\Database\Query\Expression.
    • Service Container: forbidCheckedExceptionInCallable should whitelist Laravel’s Closure bindings (e.g., App\Providers\AppServiceProvider::boot()).
    • Blade Templates: PHPStan doesn’t analyze Blade by default. Exclude resources/views from analysis unless using @php blocks.

Migration Path

  1. Phase 1: Pilot (1–2 Sprints)
    • Scope: Single Laravel module (e.g., auth or api).
    • Rules: Start with low-risk rules:
      • enforceNativeReturnTypehint (PHP 8.0+).
      • forbidCast (blacklist array/object).
      • enforceReadonlyPublicProperty (PHP 8.2+).
    • Setup:
      composer require --dev shipmonk/phpstan-rules
      ./vendor/bin/phpstan analyze --config=phpstan.neon
      
    • Validation: Manually review top 10 violations for false positives.
  2. Phase 2: Gradual Rollout
    • Expand Scope: Add rules like enforceEnumMatch or forbidCheckedExceptionInCallable.
    • CI Integration: Add PHPStan to Laravel’s CI pipeline (e.g., GitHub Actions):
      - name: PHPStan
        run: phpstan analyze --level=max --error-format=github
      
    • Whitelisting: Configure Laravel-specific exceptions (e.g., Illuminate\Validation\ValidationException).
  3. Phase 3: Full Enforcement
    • Default Ruleset: Enable all rules except those requiring custom config.
    • Documentation: Publish a CONTRIBUTING.md section on PHPStan rules for new devs.
    • Automated Fixes: Use PHPStan’s --fix where possible (e.g., adding readonly).

Compatibility

  • Laravel Versions:
    Rule Laravel 7.x Laravel 8.x Laravel 9.x Laravel 10.x
    enforceNativeReturnTypehint ❌ (PHP 7.4) ✅ (PHP 8.0)
    enforceReadonlyPublicProperty ❌ (PHP 8.0) ✅ (PHP 8.2)
    forbidCheckedExceptionInCallable
  • Dependencies:
    • PHPStan Version: Test with ^1.10 (Laravel’s default). Upgrade if rules break (e.g., enforceEnumMatch may become redundant post-PHPStan 1.10.34).
    • Laravel Packages: Check for conflicts with:
      • spatie/laravel-phpstan-stubs (for framework stubs).
      • nunomaduro/collision (if using custom exceptions).
  • Custom Code:
    • Legacy Code: Use ignoreErrors to exclude legacy
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4