psalm / plugin-symfony
Psalm Plugin for Symfony
Installs: 12 721 775
Dependents: 200
Suggesters: 2
Security: 0
Stars: 235
Watchers: 9
Forks: 57
Open Issues: 39
Language:Gherkin
Type:psalm-plugin
pkg:composer/psalm/plugin-symfony
Requires
- php: >=8.1
- ext-simplexml: *
- symfony/framework-bundle: ^5.0 || ^6.0 || ^7.0
- vimeo/psalm: ^6 || dev-master
Requires (Dev)
- doctrine/annotations: ^1.8|^2
- doctrine/orm: ^2.9
- phpunit/phpunit: ~7.5 || ~9.5
- symfony/cache-contracts: ^1.0 || ^2.0
- symfony/console: *
- symfony/form: ^5.0 || ^6.0 || ^7.0
- symfony/messenger: ^5.0 || ^6.0 || ^7.0
- symfony/security-core: *
- symfony/serializer: ^5.0 || ^6.0 || ^7.0
- symfony/validator: *
- twig/twig: ^2.10 || ^3.0
- weirdan/codeception-psalm-module: dev-master
Suggests
- weirdan/doctrine-psalm-plugin: If Doctrine is used, it is recommended install this plugin
- 5.x-dev
- v5.2.7
- v5.2.6
- v5.2.5
- v5.2.4
- v5.2.3
- v5.2.2
- v5.2.1
- v5.2.0
- v5.1.0
- v5.0.5
- v5.0.4
- v5.0.3
- v5.0.2
- v5.0.1
- v5.0.0
- 4.x-dev
- v4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- 3.x-dev
- v3.1.10
- v3.1.9
- v3.1.8
- v3.1.7
- v3.1.6
- v3.1.5
- v3.1.4
- v3.1.3
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v2.x-dev
- v2.5.1
- v2.5.0
- v2.4.0
- v2.3.1
- v2.3.0
- v2.2.4
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.5.0
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- dev-dependabot/github_actions/actions/checkout-5
- dev-php84
- dev-master
- dev-1x
This package is auto-updated.
Last update: 2025-10-01 23:10:51 UTC
README
Installation
composer require --dev psalm/plugin-symfony
vendor/bin/psalm --init
vendor/bin/psalm-plugin enable psalm/plugin-symfony
Versions & Dependencies
| Symfony Psalm Plugin | PHP | Symfony | Psalm |
|---|---|---|---|
| 5.x | ^8.1 | 5, 6, 7 | 6 |
| 4.x | ^7.4, ^8.0 | 4, 5, 6 | 4 |
| 3.x | ^7.1, ^8.0 | 4, 5, 6 | 4 |
| 2.x | ^7.1, ^8.0 | 4, 5 | 4 |
| 1.x | ^7.1 | 3, 4, 5 | 3 |
Features
- Detects the
ContainerInterface::get()result type. Works better if you configure a compiled container XML file. - Detects parameter return types from
ContainerInterface::getParameter(). - Supports Service Subscribers. Works only if you configure a compiled container XML file.
- Detects return types from console arguments (
InputInterface::getArgument()) and options (InputInterface::getOption()). Enforces to use "InputArgument" and "InputOption" constants as a best practice. - Detects Doctrine repository classes associated to entities when configured via annotations.
- Fixes
PossiblyInvalidArgumentforSymfony\Component\HttpFoundation\Request::getContent(). The plugin determines the real return type by checking the given argument and marks it as either "string" or "resource". - Detects the return type of
Symfony\Component\HttpFoundation\HeaderBag::get()by checking the default value (third argument for < Symfony 4.4). - Detects the return types of
Symfony\Component\Messenger\Envelope::lastandSymfony\Component\Messenger\Envelope::all, based on the provided argument. - Taint analysis for Symfony.
- Detects services and parameters naming conventions violations.
- Complains when
Containeris injected in a service, and asks to use dependency-injection instead. - Fixes
PropertyNotSetInConstructorfalse positive issues:- $container in AbstractController
- $context in ConstraintValidator classes
- properties in custom
@Annotationclasses
- And much more!
Configuration
If you follow the installation instructions, the psalm-plugin command will add this plugin configuration to the psalm.xml configuration file.
<?xml version="1.0"?> <psalm errorLevel="1"> <!-- project configuration --> <plugins> <pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin" /> </plugins> </psalm>
To be able to detect return types of services using ID (generally starts with @ in Symfony YAML config files. Ex: logger service)
containerXml must be provided.
Example:
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"> <containerXml>var/cache/dev/App_KernelDevDebugContainer.xml</containerXml> </pluginClass>
This file path may change based on your Symfony version, file structure and environment settings. Default files are:
- Symfony 3:
var/cache/dev/srcDevDebugProjectContainer.xml - Symfony 4:
var/cache/dev/srcApp_KernelDevDebugContainer.xml - Symfony 5+:
var/cache/dev/App_KernelDevDebugContainer.xml
Multiple container files can be configured. In this case, the first valid file is taken into account. If none of the given files is valid, a configuration exception is thrown. Example:
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"> <containerXml>var/cache/dev/App_KernelDevDebugContainer.xml</containerXml> <containerXml>var/cache/dev/App_KernelTestDebugContainer.xml</containerXml> </pluginClass>
If you're using PHP config files for Symfony 5.3+, you also need this for auto-loading of Symfony\Config:
<extraFiles> <directory name="var/cache/dev/Symfony/Config" /> <!-- https://github.com/psalm/psalm-plugin-symfony/issues/201 --> </extraFiles>
If you're using Symfony's env() or param() functions in your PHP config files, you also need this for auto-loading them:
<stubs> <file name="vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php" /> </stubs>
If you're getting the following error
MissingFile - config/preload.php - Cannot find file ...var/cache/prod/App_KernelProdContainer.preload.php to include
...you can suppress it like this:
<issueHandlers> <MissingFile> <!-- https://github.com/psalm/psalm-plugin-symfony/issues/205 --> <errorLevel type="suppress"> <file name="config/preload.php" /> </errorLevel> </MissingFile> </issueHandlers>
Symfony version
By default, the plugin uses the Kernel::MAJOR_VERSION constant to determine your version of Symfony. However, this
might not be accurate if you have Psalm installed globally. You can set the version explicitly using
the symfonyMajorVersion configuration option:
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"> <symfonyMajorVersion>6</symfonyMajorVersion> </pluginClass>
Twig tainting (experimental)
When it comes to taint analysis for Twig templates, there are currently two approaches:
- The first one is based on a specific file analyzer (
Psalm\SymfonyPsalmPlugin\Twig\TemplateFileAnalyzer) which leverages the Twig parser and visits the AST nodes. - The second one is based on the already compiled Twig templates, it only bridges calls from
Twig\Environment::renderto the actualdoRendermethod of the compiled template.
Twig Analyzer
This approach is more robust since it relies on the official Twig parser and node visitor mechanisms. For the moment, it is only able to detect simple tainted paths.
To leverage the real Twig file analyzer, you have to configure a checker for the .twig extension as follows:
<fileExtensions> <extension name=".php" /> <extension name=".twig" checker="/vendor/psalm/plugin-symfony/src/Twig/TemplateFileAnalyzer.php"/> </fileExtensions>
See the currently supported cases.
Cache Analyzer
This approach is "dirtier", since it tries to connect the taints from the application code to the compiled PHP code representing a given template. It is theoretically able to detect more taints than the previous approach out-of-the-box, but it still lacks ways to handle inheritance and stuff like that.
To allow the analysis through the cached template files, you have to add the twigCachePath entry to the plugin configuration :
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"> <twigCachePath>/cache/twig</twigCachePath> </pluginClass>
See the currently supported cases.
Credits
- Plugin created by @seferov
- @weirdan for codeception psalm module