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

Plugin Symfony Laravel Package

psalm/plugin-symfony

Psalm plugin for Symfony: improves static analysis with accurate container service/parameter typing, service subscriber support, console input types, Doctrine repository mapping, Symfony-specific fixes, naming convention checks, DI warnings, and taint analysis.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the plugin as a dev dependency and enabling it in your project. Run:

composer require --dev psalm/plugin-symfony
vendor/bin/psalm --init
vendor/bin/psalm-plugin enable psalm/plugin-symfony

The --init command will generate a psalm.xml file, and the enable command will register the plugin and add basic configuration. The first thing to do after installation is to generate and configure a compiled container XML (App_KernelDevDebugContainer.xml for Symfony 5+) — this unlocks accurate type inference for services and parameters:

<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin">
    <containerXml>var/cache/dev/App_KernelDevDebugContainer.xml</containerXml>
</pluginClass>

Your first use case will be catching correct and incorrect service usage — e.g., Psalm will now know @get('logger') returns a LoggerInterface, and warn if you call non-existent services. Run vendor/bin/psalm to see the improvement.

Implementation Patterns

  • Service & Parameter Types: With containerXml configured, Psalm infers exact types for service IDs (get('app.service.foo')) and parameters (getParameter('kernel.debug')). Use DI-only injection instead of auto-wiring for maximal precision: type-hint services explicitly on constructors.

  • Console Commands: Psalm now knows InputInterface::getArgument('id') returns the correct type (e.g., int if InputArgument::REQUIRED + typecast or if used with IntegerInputArgument). Enforce best practice by using constants like InputArgument::REQUIRED (not hardcoded strings).

  • Doctrine Repositories: If your entity uses #[ORM\Entity(repositoryClass: App\Repository\UserRepository::class)] or annotations, entityManager->getRepository(User::class) resolves to UserRepository, enabling IDE and Psalm autocompletion.

  • Twig Tainting (Security): For apps concerned about XSS, enable taint analysis by configuring either:

    • twigCachePath (simpler, uses compiled templates), or
    • fileExtensions with the TemplateFileAnalyzer (more robust, uses AST). This catches unsanitized variables passed to render().
  • Request Handling: Request::getContent() now correctly typed as string|resource depending on context. This avoids PossiblyInvalidArgument false positives when passing to json_decode().

  • Suppressing Noise: In psalm.xml, suppress common false positives like missing preload files (config/preload.php) using <issueHandlers><MissingFile>...</MissingFile></issueHandlers>.

Gotchas and Tips

  • Container Cache Must Be Warm: Psalm needs a compiled container XML — ensure you run bin/console c:c --warm or at least bin/console cache:warm before running Psalm in CI or locally. The cache file is often excluded from .gitignore, so don’t assume it’s present on first checkout.

  • Service Naming Matters: The plugin enforces Symfony naming conventions (e.g., snake_case for parameters, PascalCase for services). If you use non-conventional IDs, either rename or temporarily suppress via @psalm-suppress or config.

  • Explicit Symfony Version: If Psalm is run globally or your Kernel::MAJOR_VERSION is inaccurate (e.g., in polyglot tooling environments), set symfonyMajorVersion explicitly — especially important for pre-release Symfony versions (7, 8).

  • Env/Param Stubs Required for PHP Config: If you use env() or param() in config/packages/*.php or config/services.php, add the ContainerConfigurator.php stub and ensure var/cache/dev/Symfony/Config is added to extraFiles. Without this, config loading may fail silently.

  • Twig Analyzer vs Cache Analyzer: Use Twig Analyzer for cleaner analysis (it parses .twig directly), but use Cache Analyzer if you rely heavily on template inheritance or need broader coverage without reconfiguring .twig file extensions.

  • Dependency Injection Warning: The plugin flags direct use of ContainerInterface injection (especially AbstractController::$container) — use typed service injection instead. When refactoring, use Psalm to surface remaining container->get() calls quickly.

  • Minor Version Mismatch: If you get ServiceNotFoundException or incorrect types, double-check the containerXml file matches your current environment (dev, test, prod) — mixing App_KernelTestDebugContainer.xml with a prod config causes subtle bugs.

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
milesj/emojibase
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