psalm
Psalm is an advanced static analysis tool for PHP that provides comprehensive type checking, security analysis, and code quality assessment. Developed by Vimeo, it offers sophisticated analysis capabilities that go beyond traditional linting to catch subtle bugs and security vulnerabilities.
Key Features:
- Gradual Type Checking: Intelligent type inference that works with existing PHP code, gradually adding type safety
- Security Analysis: Built-in taint analysis to detect potential security vulnerabilities like SQL injection and XSS
- Advanced Type System: Support for generics, template types, conditional return types, and complex type relationships
- Dead Code Detection: Identifies unused variables, methods, properties, and imports to help reduce codebase bloat
- Immutability Analysis: Tracks object mutability and detects potential side effects in functional programming patterns
- Language Server: Real-time analysis and intelligent code completion through Language Server Protocol
- Migration Tools: Automated refactoring tools to add type annotations and improve code quality
- Framework Integration: Specialized support for popular PHP frameworks with framework-specific analysis rules
- Performance Optimized: Fast analysis with caching and incremental checking for large codebases
psalm documentation
- Version in MegaLinter: Psalm.6.12.0@
- Visit Official Web Site
- See How to configure psalm rules
- If custom
psalm.xml
config file isn't found, psalm.xml will be used
- If custom
- See How to disable psalm rules in files
- See Index of problems detected by psalm
Configuration in MegaLinter
- Enable psalm by adding
PHP_PSALM
in ENABLE_LINTERS variable - Disable psalm by adding
PHP_PSALM
in DISABLE_LINTERS variable
Variable | Description | Default value |
---|---|---|
PHP_PSALM_ARGUMENTS | User custom arguments to add in linter CLI call Ex: -s --foo "bar" |
|
PHP_PSALM_COMMAND_REMOVE_ARGUMENTS | User custom arguments to remove from command line before calling the linter Ex: -s --foo "bar" |
|
PHP_PSALM_FILTER_REGEX_INCLUDE | Custom regex including filter Ex: (src\|lib) |
Include every file |
PHP_PSALM_FILTER_REGEX_EXCLUDE | Custom regex excluding filter Ex: (test\|examples) |
Exclude no file |
PHP_PSALM_CLI_LINT_MODE | Override default CLI lint mode - file : Calls the linter for each file- list_of_files : Call the linter with the list of files as argument- project : Call the linter from the root of the project |
list_of_files |
PHP_PSALM_FILE_EXTENSIONS | Allowed file extensions. "*" matches any extension, "" matches empty extension. Empty list excludes all filesEx: [".py", ""] |
[".php"] |
PHP_PSALM_FILE_NAMES_REGEX | File name regex filters. Regular expression list for filtering files by their base names using regex full match. Empty list includes all files Ex: ["Dockerfile(-.+)?", "Jenkinsfile"] |
Include every file |
PHP_PSALM_PRE_COMMANDS | List of bash commands to run before the linter | None |
PHP_PSALM_POST_COMMANDS | List of bash commands to run after the linter | None |
PHP_PSALM_UNSECURED_ENV_VARIABLES | List of env variables explicitly not filtered before calling PHP_PSALM and its pre/post commands | None |
PHP_PSALM_CONFIG_FILE | psalm configuration file nameUse LINTER_DEFAULT to let the linter find it |
psalm.xml |
PHP_PSALM_RULES_PATH | Path where to find linter configuration file | Workspace folder, then MegaLinter default rules |
PHP_PSALM_DISABLE_ERRORS | Run linter but consider errors as warnings | false |
PHP_PSALM_DISABLE_ERRORS_IF_LESS_THAN | Maximum number of errors allowed | 0 |
PHP_PSALM_CLI_EXECUTABLE | Override CLI executable | ['psalm'] |
IDE Integration
Use psalm in your favorite IDE to catch errors before MegaLinter !
IDE | Extension Name | Install | |
---|---|---|---|
IDEA | PHPStan / Psalm / Generics | ||
Visual Studio Code | Psalm VSCode Plugin | ![]() |
MegaLinter Flavors
This linter is available in the following flavors
Flavor | Description | Embedded linters | Info | |
---|---|---|---|---|
![]() |
all | Default MegaLinter Flavor | 127 | |
cupcake | MegaLinter for the most commonly used languages | 88 | ||
php | Optimized for PHP based projects | 55 |
Behind the scenes
How are identified applicable files
- File extensions:
.php
How the linting is performed
- psalm is called once with the list of files as arguments (
list_of_files
CLI lint mode)
Example calls
psalm myfile.php
psalm myfile.php mydir/
psalm --config=psalm.xml myfile.php
psalm --config=psalm.xml myfile.php mydir/
Help content
Usage:
psalm [options] [file...]
Basic configuration:
-c, --config=psalm.xml
Path to a psalm.xml configuration file. Run psalm --init to create one.
--use-ini-defaults
Use PHP-provided ini defaults for memory and error display
--memory-limit=LIMIT
Use a specific memory limit. Cannot be combined with --use-ini-defaults
--disable-extension=[extension]
Used to disable certain extensions while Psalm is running.
--force-jit
If set, requires JIT acceleration to be available in order to run Psalm, exiting immediately if it cannot be enabled.
--threads=INT
If greater than one, Psalm will run the scan and analysis on multiple threads, speeding things up.
--scan-threads=INT
If greater than one, Psalm will run the scan on multiple threads, speeding things up (if specified, takes priority over the --threads flag).
--no-diff
Turns off Psalm’s diff mode, checks all files regardless of whether they’ve changed.
--php-version=PHP_VERSION
Explicitly set PHP version to analyse code against.
--error-level=ERROR_LEVEL
Set the error reporting level
Surfacing issues:
--show-info[=BOOLEAN]
Show non-exception parser findings (defaults to false).
--show-snippet[=true]
Show code snippets with errors. Options are 'true' or 'false'
--find-dead-code[=auto]
--find-unused-code[=auto]
Look for unused code. Options are 'auto' or 'always'. If no value is specified, default is 'auto'
--find-unused-psalm-suppress
Finds all @psalm-suppress annotations that aren’t used
--find-references-to=[class|method|property]
Searches the codebase for references to the given fully-qualified class or method,
where method is in the format class::methodName
--no-suggestions
Hide suggestions
--taint-analysis
Run Psalm in taint analysis mode – see https://psalm.dev/docs/security_analysis for more info
--dump-taint-graph=OUTPUT_PATH
Output the taint graph using the DOT language – requires --taint-analysis
Issue baselines:
--set-baseline[=PATH]
Save all current error level issues to a file, to mark them as info in subsequent runs
Add --include-php-versions to also include a list of PHP extension versions
Default value is `psalm-baseline.xml`
--use-baseline=PATH
Allows you to use a baseline other than the default baseline provided in your config
--ignore-baseline
Ignore the error baseline
--update-baseline
Update the baseline by removing fixed issues. This will not add new issues to the baseline
Add --include-php-versions to also include a list of PHP extension versions
Plugins:
--plugin=PATH
Executes a plugin, an alternative to using the Psalm config
Output:
-m, --monochrome
Enable monochrome output
--output-format=console
Changes the output format.
Available formats:
by-issue-level, checkstyle, codeclimate, compact, console, count, emacs,
github, json, json-summary, junit, phpstorm, pylint, sarif, sonarqube,
text, xml
--no-progress
Disable the progress indicator
--long-progress
Use a progress indicator suitable for Continuous Integration logs
--stats
Shows a breakdown of Psalm’s ability to infer types in the codebase
Reports:
--report=PATH
The path where to output report file. The output format is based on the file extension.
(Currently supported formats: ".console", ".emacs", ".json", ".pylint", ".sarif", ".sarif.json", ".txt",
".xml", "checkstyle.xml", "codeclimate.json", "count.txt", "junit.xml",
"sonarqube.json", "summary.json")
--report-show-info[=BOOLEAN]
Whether the report should include non-errors in its output (defaults to true)
Caching:
--consolidate-cache
Consolidates all cache files that Psalm uses for this specific project into a single file,
for quicker runs when doing whole project scans.
Make sure to consolidate the cache again after running Psalm before saving the cache via CI.
--clear-cache
Clears all cache files that Psalm uses for this specific project
--clear-global-cache
Clears all cache files that Psalm uses for all projects
--no-cache
Runs Psalm without using cache
--no-reflection-cache
Runs Psalm without using cached representations of unchanged classes and files.
Useful if you want the afterClassLikeVisit plugin hook to run every time you visit a file.
--no-reference-cache
Runs Psalm without using cached representations of unchanged methods.
--no-file-cache
Runs Psalm without using caching every single file for later diffing.
This reduces the space Psalm uses on disk and file I/O.
Miscellaneous:
-h, --help
Display this help message
-v, --version
Display the Psalm version
-i, --init [source_dir=src] [level=3]
Create a psalm config file in the current directory that points to [source_dir]
at the required level, from 1, most strict, to 8, most permissive.
--debug
Debug information
--debug-by-line
Debug information on a line-by-line level
--debug-emitted-issues
Print a php backtrace to stderr when emitting issues.
-r, --root
If running Psalm globally you’ll need to specify a project root. Defaults to cwd
--generate-json-map=PATH
Generate a map of node references and types in JSON format, saved to the given path.
--generate-stubs=PATH
Generate stubs for the project and dump the file in the given path
--shepherd[=endpoint]
Send analysis statistics to Shepherd (shepherd.dev) or your server.
--alter
Run Psalter
--review
Run the psalm-review tool
--language-server
Run Psalm Language Server
Installation on mega-linter Docker image
- Dockerfile commands :
# Parent descriptor install
RUN update-alternatives --install /usr/bin/php php /usr/bin/php84 110
COPY --from=composer/composer:2-bin /composer /usr/bin/composer
ENV PATH="/root/.composer/vendor/bin:${PATH}"
ENV PHP_CS_FIXER_IGNORE_ENV=true
# Linter install
# renovate: datasource=packagist depName=vimeo/psalm
ARG PHP_VIMEO_PSALM_VERSION=6.12.0
RUN GITHUB_AUTH_TOKEN="$(cat /run/secrets/GITHUB_TOKEN)" && export GITHUB_AUTH_TOKEN && composer global require vimeo/psalm:${PHP_VIMEO_PSALM_VERSION}