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

Technical Evaluation

Architecture Fit

  • Strengths:

    • Strictness Alignment: The package complements Laravel’s existing PHPStan setup by enforcing stricter type safety, immutability, and best practices (e.g., readonly properties, match for enums, forbidding unsafe casts). This aligns with Laravel’s evolving PHP 8.x+ features (e.g., enums, attributes, generics).
    • Modularity: Rules are granular and configurable, allowing TPMs to enable/disable rules per team or project needs (e.g., enforceReadonlyPublicProperty for immutable DTOs, forbidCast for type safety).
    • PHPStan Synergy: Leverages PHPStan’s existing ecosystem (e.g., stubFiles for BackedEnumGenerics), reducing duplication and tooling overhead.
    • Laravel-Specific Pain Points: Targets common Laravel anti-patterns (e.g., loose array handling in iterator_to_array, checked exceptions in closures for queues/jobs).
    • Maturity Signal (4.4.1): The patch release is narrowly scoped to precision fixes in two high-friction rules, indicating the maintainers are actively tuning false-positive behaviour rather than adding surface area — a good sign for adoption in legacy Laravel codebases.
  • Gaps:

    • Laravel-Specific Rules Missing: No built-in rules for Laravel’s ecosystem (e.g., Eloquent model methods, Blade templates, or service container bindings). TPMs must manually configure or extend rules.
    • Performance Overhead: ~40 rules may slow down CI/CD pipelines if not optimized (e.g., parallelizing PHPStan runs or excluding tests).
    • PHP Version Dependencies: Some rules (e.g., enforceReadonlyPublicProperty) are PHP 8.2+ only, requiring version gates or polyfills.

Integration Feasibility

  • Composer Integration: Zero-friction via composer require --dev, with minimal config changes (e.g., adding includes to phpstan.neon). Pin to ^4.4.1 to pick up the callable-resolution fixes.
  • Configuration Overhead: Low for basic use; higher for custom rules (e.g., classSuffixNaming requires mapping superclasses to suffixes). TPMs can start with defaults and refine.
  • Tooling Compatibility:
    • IDE Support: Works with PHPStorm/VSCode PHPStan plugins for real-time feedback.
    • CI/CD: Integrates with GitHub Actions/GitLab CI via phpstan/extension-installer or custom scripts.
    • Laravel Tools: Compatible with Laravel Pint (for code formatting) and PestPHP (for testing), but no native integration.

Technical Risk

  • False Positives/Negatives (revised in 4.4.1):
    • Reduced — forbidCheckedExceptionInCallable: 4.4.1 resolves the static-call caller type from expressions (#368). This removes a class of incorrect reports on static dispatch and should materially reduce noise in code that uses Laravel facades, static helpers, and container ::make()/::resolve() patterns. Prior mitigations via allowedCheckedExceptionCallables may now be removable.
    • Reduced — requirePreviousExceptionPass: 4.4.1 accepts an exception passed to a nested call (#369). Wrapping/rethrowing patterns such as throw new X(..., previous: $e) nested inside another call no longer produce false positives, which was a common friction point in Laravel exception-handling and job-retry code.
    • Residual risk: Rules like enforceEnumMatch may still flag legitimate patterns (e.g., dynamic closures in Laravel’s tap() or when()). forbidCast may still break legacy code using (array) on null; mitigate with blacklist exceptions.
  • Maintenance Burden:
    • Rules tied to PHPStan versions (e.g., enforceEnumMatch for PHPStan 1.10.x quirks). TPMs must monitor updates and adjust configs.
    • Custom stubs (e.g., BackedEnumGenerics) require manual stub file management.
  • Team Adoption:
    • Strict rules (e.g., forbidArithmeticOperationOnNonNumber) may cause friction. TPMs should phase them in (e.g., warn-only mode first).
    • Documentation gap: No Laravel-specific examples (e.g., how to configure for Eloquent models).
    • Adoption argument improved: 4.4.1 lowers the "tool cries wolf" objection for two of the highest-friction rules, making it easier to justify enabling them early rather than deferring.

Key Questions for TPMs

  1. Prioritization:
    • Which rules align with Laravel’s current tech debt (e.g., enforceNativeReturnTypehint for legacy methods vs. forbidCast for new code)?
    • Should rules be enabled in CI first (fail builds) or locally (educate devs)?
  2. Configuration Strategy:
    • Centralized config (e.g., in phpstan.neon) vs. per-repo overrides?
    • How to handle legacy code? (e.g., exclude directories or use ignoreErrors).
    • New: Which allowedCheckedExceptionCallables and requirePreviousExceptionPass suppressions can be deleted now that 4.4.1 fixes the underlying resolution? Audit the allowlists for dead entries before they mask real issues.
  3. Performance:
    • Will PHPStan runs exceed time budgets in CI? Test with --memory-limit and --parallel.
  4. Laravel-Specific Extensions:
    • Should TPMs extend the package to add Laravel rules (e.g., for HasFactory traits or Nova resources)?
  5. Monitoring:
    • Track false positives/negatives via PHPStan’s --error-format=json and custom scripts.
    • Set up dashboards (e.g., GitHub Insights) to monitor rule violations over time.
    • Compare violation counts before/after the 4.4.1 bump to confirm the expected drop in forbidCheckedExceptionInCallable and requirePreviousExceptionPass reports; an unchanged count suggests the suppressions were masking something else.

Integration Approach

Stack Fit

  • PHPStan Ecosystem: Designed for PHPStan, so integration is seamless with existing setups (e.g., Laravel’s phpstan-baseline.php for legacy code).
  • Laravel Compatibility:
    • Pros: Enforces modern PHP practices (e.g., readonly, match) that Laravel 9+ encourages. 4.4.1’s static-call resolution fix improves behaviour specifically on facade- and container-style static dispatch.
    • Cons: No native support for Laravel-specific patterns (e.g., Illuminate\Support\Collection methods). TPMs must manually whitelist or configure exceptions.
  • Toolchain Synergy:
    • PestPHP: Rules like forbidCheckedExceptionInCallable help catch issues in test doubles or mocks.
    • Laravel Pint: Can pair with PHPStan for "fixable" violations (e.g., enforceNativeReturnTypehint).
    • Telescope/Sentry: Rules like forbidCheckedExceptionInYieldingMethod reduce runtime errors in queues/jobs.

Migration Path

  1. Phase 1: Audit and Baseline
    • Run PHPStan with default rules to establish a baseline (phpstan analyse --generate-baseline).
    • Identify high-impact rules (e.g., forbidCast, enforceReadonlyPublicProperty) and enable them incrementally.
  2. Phase 2: Configure for Laravel
    • Whitelist Laravel-specific patterns:
      parameters:
          shipmonkRules:
              forbidCast:
                  blacklist!: ['(array)'] # Allow (array) on Collections
              forbidCheckedExceptionInCallable:
                  allowedCheckedExceptionCallables:
                      'Illuminate\Queue\CallQueuedHandler::handle': 0 # Allow in jobs
      
    • Exclude legacy directories (e.g., vendor, storage/framework/views).
  3. Phase 3: Enforce in CI
    • Add to .github/workflows/phpstan.yml:
      - name: PHPStan
        run: phpstan analyse --level=max --error-format=github
      
    • Start with --fix for auto-fixable rules (e.g., enforceNativeReturnTypehint).
  4. Phase 4: Educate and Refine
    • Document rule justifications (e.g., "Why we forbid (array) casts").
    • Run workshops to address common violations (e.g., enforceEnumMatch for enum handling).

Compatibility

  • PHP Version: Rules like enforceReadonlyPublicProperty require PHP 8.2+. Use feature flags or polyfills for older versions.
  • PHPStan Version: Test with PHPStan’s latest stable (e.g., 1.10.x) to avoid rule conflicts (e.g., enforceEnumMatch for PHPStan 1.10.0–1.10.34 quirks). Validate 4.4.1 against your pinned PHPStan version before rollout — the #368 fix changes caller-type resolution and can shift results on existing baselines.
  • Laravel Version:
    • Laravel 9+: Full compatibility (PHP 8.0+).
    • Laravel 8.x: Partial compatibility (exclude rules requiring PHP 8.1+ features like BackedEnumGenerics).
  • Dependencies: No conflicts with Laravel’s core or popular packages (e.g., laravel/framework, spatie/laravel-package-tools).

Sequencing

  1. Start with Safe Rules:
    • Enable non-breaking rules first (e.g., enforceNativeReturnTypehint, enforceIteratorToArrayPreserveKeys).
  2. Add Strictness Gradually:
    • Week 1: forbidCast, forbidArithmeticOperationOnNonNumber.
    • Week 2: enforceReadonlyPublicProperty, enforceClosureParamNativeTypehint.
    • Week 3: forbidCheckedExceptionInCallable, enforceEnumMatch — now the preferred entry point for these two given the 4.4.1 precision fixes.
  3. Legacy Code Handling:
    • Use ignoreErrors for known issues:
      ignoreErrors:
          - '#Method .* has no PHPDoc or return typehint#' # For old controllers
      
    • Refactor incrementally (e.g., one module at a time).
    • After the 4.4.1 bump: regenerate the baseline and re-run. Removing stale baseline entries and suppressions is the fastest way to convert the upstream fixes into real signal.
  4. Performance Optimization:
    • Exclude large directories (e.g., storage/logs) or use --exclude-paths.
    • Cache results with phpstan --cache-results.

Operational Impact

Maintenance

  • Configuration Drift: Rules may need updates as PHPStan/Laravel evolve (e.g., enforceEnumMatch for PHPStan 1.11+). TPMs should:
    • Subscribe to PHPStan’s changelog.
    • Schedule quarterly reviews of enabled rules.
    • Track this package’s releases separately; 4.4.1 is a low-risk patch, but precision changes to rules mean baselines may shrink or shift.
  • Rule Deprecation and Behaviour Changes: Monitor release notes for rule semantics changes. Bug fixes that reduce false positives are effectively behaviour changes for CI — a green build may go greener, or a previously suppressed error may surface once a suppression is removed. Treat 4.4.1 as a low-risk, high-value upgrade and schedule it in the next maintenance window rather than a big-bang rollout.
  • Config Debt from Suppressions: Allowlists for forbidCheckedExceptionInCallable and nested-exception workarounds for requirePreviousExceptionPass are now partly obsolete. Assign ownership for pruning them; stale suppressions silently erode the value of the rule set.

Support

  • Upstream Responsiveness: The 4.4.1 turnaround on two reported issues (#368, #369) with named contributors indicates an active, issue-driven maintenance cadence — a positive support signal for a dev-tooling dependency.
  • Internal Support Model: Designate a tooling owner (platform/DevEx) to triage new violations, maintain phpstan.neon, and decide suppression vs. refactor. Without a named owner, allowlists accrete.
  • Escalation Path: For false positives, file upstream with a minimal repro; in the interim, use ignoreErrors scoped to path and message rather than disabling the rule globally.

Scaling

  • CI Cost: Rule count and codebase size are the main drivers. Use --parallel, --memory-limit, and path exclusions; measure before adding all ~40 rules to large monorepos.
  • Multi-Repo Rollout: Standardize on a pinned version range (e.g., ^4.4.1) and a shared config package so teams inherit the same rule set; per-repo overrides should be additive and reviewed.
  • Monorepo Considerations: Per-package baselines keep noise isolated and let teams adopt strictness at different rates without blocking the whole build.

Failure Modes

  • CI Breakage on Upgrade: Precision fixes can change reported errors on existing baselines. Mitigate by running the upgrade on a branch, diffing violation output, and regenerating baselines in the same PR.
  • Over-Suppression: Allowlists added pre-4.4.1 that are never revisited permanently mute rules. Mitigate with periodic audits and expiry comments/dates on suppressions.
  • Silent Rule Drift: PHPStan upgrades can disable or alter rules without obvious failure. Pin both PHPStan and this package, and treat config changes as reviewed code.
  • Adoption Abandonment: Strict rules landing without education leads teams to blanket-ignore paths. Mitigate with phased enablement, documented rationale, and a warn-only period.

Ramp-Up

  • Effort: Low for the 4.4.1 upgrade (patch dependency bump plus baseline regeneration); moderate for the broader rule rollout (weeks, phased as in Sequencing).
  • Learning Curve: Developers need familiarity with PHPStan output, baseline workflow, and the intent behind stricter rules; TPMs need fluency in suppression vs. refactor trade-offs.
  • Enablement Plan: One short kickoff on why the rules exist, a documented "how to fix / how to suppress" guide, and a named owner for violation triage during the first sprint after enforcement.
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table