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

Doctrine Psalm Plugin Laravel Package

weirdan/doctrine-psalm-plugin

Psalm plugin for Doctrine ORM projects. Adds smarter type inference for EntityManager, repositories, proxies and collections, reducing false positives and improving static analysis of Doctrine entities and queries in PHP applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Doctrine Integration: The plugin is explicitly designed for Doctrine ORM (used in Laravel via doctrine/dbal and illuminate/database wrappers), making it a near-perfect fit for Laravel applications leveraging Eloquent’s underlying ORM patterns. The plugin’s ability to infer types for entities, repositories, and proxies aligns with Laravel’s repository pattern (via custom repositories) and Eloquent model abstractions.
  • Psalm Compatibility: Since Laravel’s ecosystem increasingly adopts static analysis tools (e.g., PHPStan, Psalm), this plugin integrates seamlessly with existing type-checking workflows. It reduces noise in Psalm’s output by contextualizing Doctrine-specific behaviors (e.g., lazy-loaded proxies, dynamic metadata).
  • Domain Model Safety: The plugin’s focus on type inference for ORM operations (e.g., EntityManager::find(), repository methods) directly addresses Laravel’s pain points around runtime type safety in domain logic, especially in complex queries or polymorphic relationships.

Integration Feasibility

  • Minimal Configuration: The plugin requires only Psalm’s plugin system (no Laravel-specific hooks), making adoption straightforward. Key steps:
    1. Install via Composer (weirdan/doctrine-psalm-plugin).
    2. Configure Psalm’s plugins array in psalm.xml to include the plugin.
    3. Optionally, specify Doctrine entity paths for stricter analysis.
  • Laravel-Specific Adjustments:
    • Eloquent vs. Doctrine: While Laravel uses Eloquent, the plugin’s Doctrine ORM awareness still applies to:
      • Custom repositories extending Doctrine\ORM\EntityRepository.
      • Raw Doctrine queries (e.g., via DBAL or EntityManager injections).
      • Hybrid apps mixing Eloquent and Doctrine directly.
    • Proxy Handling: The plugin’s lazy-loading proxy support mitigates Psalm’s false positives for Illuminate\Database\Eloquent\Concerns\HasDynamicAttributes or Illuminate\Database\Eloquent\Relations\Relation proxies.
  • Dependency Conflicts: Low risk if using Doctrine ORM 2.10+ (Laravel 10+ supports this via doctrine/dbal and doctrine/orm). Older Laravel versions may need Doctrine ORM installed separately (e.g., doctrine/orm:^2.10).

Technical Risk

Risk Area Mitigation Strategy
False Positives/Negatives Start with a baseline Psalm config (e.g., --strict-typing) and gradually enable plugin features. Use psalm --init to auto-generate a config.
Performance Overhead Psalm plugins add ~10–30% runtime to static analysis. Mitigate by:
  • Running in CI with caching (--cache-dir).
  • Parallelizing analysis (--jobs=4).
  • Excluding non-critical paths (e.g., tests, migrations). | | Plugin Maturity | Last release in 2025, but low stars (87) may indicate niche adoption. Verify:
  • Compatibility with Psalm 5.x (Laravel’s current Psalm version).
  • GitHub issues for Laravel-specific edge cases (e.g., Eloquent hybrid usage). | | Breaking Changes | Monitor Doctrine ORM minor updates (e.g., 2.10 → 2.11) for plugin compatibility. |

Key Questions

  1. Scope of Analysis:
    • Does the plugin handle Eloquent-specific patterns (e.g., hasManyThrough, accessors) beyond raw Doctrine ORM?
    • How does it interact with Laravel’s service container (e.g., auto-wired repositories)?
  2. CI/CD Impact:
    • What’s the expected runtime increase for a medium Laravel app (e.g., 50 entities)?
    • Can it be incrementally enabled (e.g., start with repositories only)?
  3. False Positive Handling:
    • Are there whitelisting mechanisms for known Doctrine quirks (e.g., dynamic hydrators)?
    • How does it compare to PHPStan’s doctrine extension in accuracy?
  4. Long-Term Viability:
    • Is the maintainer (weirdan) active in the Psalm/Doctrine communities?
    • Are there plans for Laravel-specific extensions (e.g., Eloquent support)?

Integration Approach

Stack Fit

  • Primary Use Case: Laravel applications using:
    • Doctrine ORM directly (e.g., custom repositories, DDD layers).
    • Hybrid Eloquent/Doctrine (e.g., legacy systems migrating to Doctrine).
    • Strict typing (Psalm + Laravel’s return_type annotations).
  • Secondary Use Case: Symfony apps (already documented), but Laravel’s Eloquent abstractions may require additional Psalm config (e.g., mapping Eloquent models to Doctrine entities).
  • Toolchain Synergy:
    • Psalm: Leverages existing psalm.xml for plugin configuration.
    • CI: Integrates with GitHub Actions/GitLab CI via psalm --no-cache for pre-merge checks.
    • IDE: Works with PHPStorm/VSCode via Psalm’s language server.

Migration Path

  1. Preparation:
    • Audit current Psalm configuration (psalm.xml) for Doctrine-related rules (e.g., @mixin, @template).
    • Ensure Doctrine ORM is installed (if not using Eloquent directly):
      composer require doctrine/orm
      
  2. Plugin Installation:
    composer require --dev weirdan/doctrine-psalm-plugin
    
    Update psalm.xml:
    <plugin-classes>
        <plugin-class>WeirdAn\DoctrinePsalmPlugin\Plugin</plugin-class>
    </plugin-classes>
    
  3. Configuration:
    • Specify entity paths (if not auto-detected):
      <param name="entityPaths" type="string[]" description="Paths to Doctrine entities">
          <value>app/Models</value>
          <value>src/Entity</value>
      </param>
      
    • Adjust Psalm levels (e.g., --level=5 for strict typing).
  4. Incremental Rollout:
    • Start with repository analysis (low-risk).
    • Gradually enable entity and proxy checks.
    • Use --no-cache to test in CI before full adoption.

Compatibility

Component Compatibility Notes
Laravel Versions Works with Laravel 10+ (Doctrine ORM 2.10+). Older versions may need manual Doctrine setup.
Psalm Versions Tested with Psalm 5.x. Check for ^4.0 support if using older Psalm.
Doctrine ORM Requires 2.10+ (Laravel 10+ includes this via doctrine/dbal).
Eloquent Limited native support; treat Eloquent models as opaque objects unless using custom Doctrine repositories.
Custom Repositories Full support if extending Doctrine\ORM\EntityRepository.

Sequencing

  1. Phase 1: Repository Layer
    • Focus on Doctrine repositories (highest ROI for type safety).
    • Validate with psalm --no-cache --init.
  2. Phase 2: Entity Layer
    • Enable entity attribute/method analysis.
    • Resolve false positives for dynamic hydrators (e.g., @ORM\Column(type="json")).
  3. Phase 3: Proxy/Lazy-Loading
    • Tune Psalm to recognize proxy classes (e.g., Proxy\__CG__App\Models\User).
  4. Phase 4: CI Integration
    • Add to pre-commit hooks (e.g., php-cs-fixer + Psalm).
    • Set failure thresholds (e.g., block PRs with critical errors).

Operational Impact

Maintenance

  • Plugin Updates:
    • Monitor Psalm and Doctrine ORM minor versions for compatibility.
    • Update weirdan/doctrine-psalm-plugin alongside Psalm (e.g., via composer update --with-dependencies).
  • Configuration Drift:
    • Maintain a psalm.xml template in the repo to standardize across environments.
    • Document whitelisted exceptions (e.g., dynamic properties) in a PSALM_RULES.md.

Support

  • Debugging Workflow:
    • Use psalm --log-errors-to=psalm.log to diagnose plugin-specific issues.
    • Check Psalm’s issue tracker for Doctrine plugin bugs.
  • Team Onboarding:
    • Provide a cheat sheet for
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime