Configuration
Psalm uses an XML config file (by default, psalm.xml). A barebones example looks like this:
<?xml version="1.0"?>
<psalm>
<projectFiles>
<directory name="src" />
</projectFiles>
</psalm>
Configuration file may be split into several files using XInclude tags (c.f. previous example):
psalm.xml
<?xml version="1.0"?>
<psalm
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
xmlns:xi="http://www.w3.org/2001/XInclude"
>
<xi:include href="files.xml"/>
</psalm>
files.xml
<?xml version="1.0" encoding="UTF-8"?>
<projectFiles xmlns="https://getpsalm.org/schema/config">
<file name="Bar.php" />
<file name="Bat.php" />
</projectFiles>
Different configuration file
You can also create a different configuration file, then run Psalm with:
vendor/bin/psalm --config=other-psalm-config.xml
Optional <psalm /> attributes
Coding style
errorLevel
<psalm
errorLevel="[int]"
/>
reportMixedIssues
<psalm
reportMixedIssues="[bool]"
/>
"false" hides all issues with Mixed types in Psalm’s output. If not given, this defaults to "false" when errorLevel is 3 or higher, and "true" when the error level is 1 or 2.
totallyTyped
(Deprecated) This setting has been replaced by reportMixedIssues which is automatically enabled when errorLevel is 1.
resolveFromConfigFile
<psalm
resolveFromConfigFile="[bool]"
/>
New versions of Psalm enable this option when generating config files. Older versions did not include it.
useDocblockTypes
<psalm
useDocblockTypes="[bool]"
>
true.
useDocblockPropertyTypes
<psalm
useDocblockPropertyTypes="[bool]"
>
false (though only relevant if useDocblockTypes is false).
docblockPropertyTypesSealProperties
<psalm
docblockPropertyTypesSealProperties="[bool]"
>
true.
usePhpDocMethodsWithoutMagicCall
<psalm
usePhpDocMethodsWithoutMagicCall="[bool]"
>
@method annotation normally only applies to classes with a __call method. Setting this to true allows you to use the @method annotation to override inherited method return types. Defaults to false.
usePhpDocPropertiesWithoutMagicCall
<psalm
usePhpDocPropertiesWithoutMagicCall="[bool]"
>
@property, @property-read and @property-write annotations normally only apply to classes with __get/__set methods. Setting this to true allows you to use the @property, @property-read and @property-write annotations to override property existence checks and resulting property types. Defaults to false.
disableVarParsing
<psalm
disableVarParsing="[bool]"
/>
Disables parsing of @var PHPDocs everywhere except for properties. Setting this to true can remove many false positives due to outdated @var annotations, used before integrations of Psalm generics and proper typing, enforcing Single Source Of Truth principles. Defaults to false.
strictBinaryOperands
<psalm
strictBinaryOperands="[bool]"
>
true.
allowBoolToLiteralBoolComparison
<psalm
allowBoolToLiteralBoolComparison="[bool]"
>
If false, disallows comparing a boolean to a literal boolean (mostly a codestyle rule, not a bug detection rule; see RedundantIdentityWithTrue). Defaults to true.
rememberPropertyAssignmentsAfterCall
<psalm
rememberPropertyAssignmentsAfterCall="[bool]"
>
false means that any function calls will cause Psalm to forget anything it knew about object properties within the scope of the function it's currently analysing. This duplicates functionality that Hack has. Defaults to true.
allowStringToStandInForClass
<psalm
allowStringToStandInForClass="[bool]"
>
true, strings can be used as classes, meaning $some_string::someMethod() is allowed. If false, only class constant strings (of the form Foo\Bar::class) can stand in for classes, otherwise an InvalidStringClass issue is emitted. Defaults to false.
disableSuppressAll
<psalm
disableSuppressAll="[bool]"
>
true, disables wildcard suppression of all issues with @psalm-suppress all. Defaults to true.
memoizeMethodCallResults
<psalm
memoizeMethodCallResults="[bool]"
>
true, the results of method calls without arguments passed are remembered between repeated calls of that method on a given object. Defaults to false.
hoistConstants
<psalm
hoistConstants="[bool]"
>
true, constants defined in a function in a file are assumed to be available when requiring that file, and not just when calling that function. Defaults to false (i.e. constants defined in functions will only be available for use when that function is called)
addParamDefaultToDocblockType
<psalm
addParamDefaultToDocblockType="[bool]"
>
true causes it to expand the param type to include the param default. Defaults to false.
checkForThrowsDocblock
<psalm
checkForThrowsDocblock="[bool]"
>
true, Psalm will check that the developer has supplied @throws docblocks for every exception thrown in a given function or method. Defaults to false.
checkForThrowsInGlobalScope
<psalm
checkForThrowsInGlobalScope="[bool]"
>
true, Psalm will check that the developer has caught every exception in global scope. Defaults to false.
ignoreInternalFunctionFalseReturn
<psalm
ignoreInternalFunctionFalseReturn="[bool]"
>
true, Psalm ignores possibly-false issues stemming from return values of internal functions (like preg_split) that may return false, but do so rarely. Defaults to false.
ignoreInternalFunctionNullReturn
<psalm
ignoreInternalFunctionNullReturn="[bool]"
>
true, Psalm ignores possibly-null issues stemming from return values of internal array functions (like current) that may return null, but do so rarely. Defaults to false.
inferPropertyTypesFromConstructor
<psalm
inferPropertyTypesFromConstructor="[bool]"
>
true, Psalm infers property types from assignments seen in straightforward constructors. Defaults to true.
findUnusedVariablesAndParams
<psalm
findUnusedVariablesAndParams="[bool]"
>
true, Psalm will attempt to find all unused variables, the equivalent of running with --find-unused-variables. Defaults to false.
findUnusedCode
<psalm
findUnusedCode="[bool]"
>
true, Psalm will attempt to find all unused code (including unused variables), the equivalent of running with --find-unused-code. Defaults to true.
Unused-code detection is based on a graph of references between code elements, resolved by reachability from the program's entry points (the public API, top-level code, free functions, and code outside of the project directories). As a result, a class, method, property or constant that is referenced only by other unused code — including cycles of otherwise unreferenced code — is reported as unused. Suppressing an unused-code issue (e.g. @psalm-suppress UnusedClass) only silences the report for that symbol; it does not turn the symbol into an entry point, so code that only it references is still reported.
forceJit
<psalm
forceJit="[bool]"
>
true, Psalm will enable JIT acceleration and exit immediately if it cannot be enabled, the equivalent of running with --force-jit. When false (default), Psalm runs without JIT.
noCache
<psalm
noCache="[bool]"
>
true, Psalm will disable usage of the cache, the equivalent of running with --no-cache. Defaults to false.
arrayCache
<psalm
arrayCache="[bool]"
>
false, Psalm will disable usage of the array cache.
The array cache is used together with the file cache to avoid re-loading cache entries when re-scanning the same file, which offers a nice performance improvement.
Defaults to true.
disallowLiteralKeysOnUnshapedArrays
<psalm
disallowLiteralKeysOnUnshapedArrays="[bool]"
>
true, Psalm will emit issues when using literal keys on unshaped arrays (useful to enforce usage of shaped arrays). Defaults to false.
allFunctionsGlobal
<psalm
allFunctionsGlobal="[bool]"
>
true, Psalm will treat all functions declared in scanned files as available to all files, even if they aren't loaded by the Composer autoloader (useful for legacy codebases which make heavy use of require/include, instead of Composer's autoloader). Defaults to false.
allConstantsGlobal
<psalm
allConstantsGlobal="[bool]"
>
When true, Psalm will treat all constants declared in scanned files as available to all files, even if they aren't loaded by the Composer autoloader (useful for legacy codebases which make heavy use of require/include, instead of Composer's autoloader). Defaults to false.
findUnusedPsalmSuppress
<psalm
findUnusedPsalmSuppress="[bool]"
>
true, Psalm will report all @psalm-suppress annotations that aren't used, the equivalent of running with --find-unused-psalm-suppress. Defaults to false.
ensureArrayStringOffsetsExist
<psalm
ensureArrayStringOffsetsExist="[bool]"
>
true, Psalm will complain when referencing an explicit string offset on an array e.g. $arr['foo'] without a user first asserting that it exists (either via an isset check or via an object-like array). Defaults to false.
ensureArrayIntOffsetsExist
<psalm
ensureArrayIntOffsetsExist="[bool]"
>
true, Psalm will complain when referencing an explicit integer offset on an array e.g. $arr[7] without a user first asserting that it exists (either via an isset check or via an object-like array). Defaults to false.
ensureOverrideAttribute
<psalm
ensureOverrideAttribute="[bool]"
>
true, Psalm will report class and interface methods that override a method on a parent, but do not have an Override attribute. Defaults to true.
phpVersion
<psalm
phpVersion="[string]"
>
composer.json if one is present. It will check against the earliest version of PHP that satisfies the declared php dependency
This can be overridden on the command-line using the --php-version= flag which takes the highest precedence over both the phpVersion setting and the version derived from composer.json.
skipChecksOnUnresolvableIncludes
<psalm
skipChecksOnUnresolvableIncludes="[bool]"
>
When true, Psalm will skip checking classes, variables and functions after it comes across an include or require it cannot resolve. This allows code to reference functions and classes unknown to Psalm.
This defaults to false.
sealAllMethods
<psalm
sealAllMethods="[bool]"
>
When true, Psalm will treat all classes as if they had sealed methods, meaning that if you implement the magic method __call, you also have to add @method for each magic method. Defaults to true.
sealAllProperties
<psalm
sealAllProperties="[bool]"
>
When true, Psalm will treat all classes as if they had sealed properties, meaning that Psalm will disallow getting and setting any properties not contained in a list of @property (or @property-read/@property-write) annotations and not explicitly defined as a property. Defaults to true.
runTaintAnalysis
<psalm
runTaintAnalysis="[bool]"
>
When true (the default), Psalm will run Taint Analysis on your codebase. This config is the same as if you were running Psalm with --taint-analysis.
reportInfo
<psalm
reportInfo="[bool]"
>
When false, Psalm will not consider issue at lower level than errorLevel as info (they will be suppressed instead). This can be a big improvement in analysis time for big projects. However, this config will prevent Psalm to count or suggest fixes for suppressed issue
allowNamedArgumentCalls
<psalm
allowNamedArgumentCalls="[bool]"
>
When false, Psalm will not report ParamNameMismatch issues in your code anymore. This does not replace the use of individual @no-named-arguments to prevent external access to a library's method or to reduce the type to a list when using variadics
triggerErrorExits
<psalm
triggerErrorExits="[string]"
>
Describe the behavior of trigger_error. always means it always exits, never means it never exits, default means it exits only for E_USER_ERROR. Default is default
Running Psalm
autoloader
<psalm
autoloader="[string]"
>
throwExceptionOnError
<psalm
throwExceptionOnError="[bool]"
>
false.
hideExternalErrors
<psalm
hideExternalErrors="[bool]"
>
<projectFiles>. Defaults to false.
hideAllErrorsExceptPassedFiles
<psalm
hideAllErrorsExceptPassedFiles="[bool]"
>
false.
cacheDirectory
<psalm
cacheDirectory="[string]"
>
Defaults to $XDG_CACHE_HOME/psalm. If $XDG_CACHE_HOME is either not set or empty, a default equal to $HOME/.cache/psalm is used or sys_get_temp_dir() . '/psalm' when not defined.
allowFileIncludes
<psalm
allowFileIncludes="[bool]"
>
require/include calls in your PHP. Defaults to true.
ignoreIncludeSideEffects
<psalm
ignoreIncludeSideEffects="[bool]"
>
Ignoring include side effects can significantly speed up scans on legacy codebases, but changes to variables or variables defined inside of included files will not be visible to Psalm (functions, constants and classes will still be visible anyway, especially if the hoistConstants, allConstantsGlobal, allFunctionsGlobal configuration parameters are set to true).
Defaults to false.
respectIncludeOnce
<psalm
respectIncludeOnce="[bool]"
>
require_once() or include_once() call.
By default, Psalm treats require_once() and include_once() calls as if they were require() or include() calls in an attempt to consider all possible permutations of file include order. Respecting require_once() and include_once() behavior can significantly speed up scans on codebases with circular require_once() or include_once() calls. While potentially less comprehensive, this setting aims to more closely mimic PHP's runtime behavior.
Defaults to false.
serializer
<psalm
serializer="['igbinary'|'default']"
>
ext-igbinary if the version is greater than or equal to 2.0.5, otherwise it defaults to PHP's built-in serializer.
compressor
<psalm
compressor="['lz4'|'deflate'|'off']"
>
ext-zlib deflate, if it's enabled.
threads
<psalm
threads="[int]"
>
--threads on the command line). This value will be used in place of detecting threads from the host machine, but will be overridden by using --threads or --debug (which sets threads to 1) on the command line
scanThreads
<psalm
scanThreads="[int]"
>
threads field) (similar to --scan-threads on the command line). This value will be used in place of detecting threads from the host machine, but will be overridden by using --scan-threads or --debug (which sets threads to 1) on the command line.
maxStringLength
<psalm
maxStringLength="1000"
>
non-empty-string type, instead.
Please note that changing this setting might introduce unwanted side effects and those side effects won't be considered as bugs.
maxShapedArraySize
<psalm
maxShapedArraySize="100"
>
array{key1: "value", key2: T} type during Psalm analysis.
Arrays bigger than this value (100 by default) will be transformed in a generic non-empty-array type, instead.
Please note that changing this setting might introduce unwanted side effects and those side effects won't be considered as bugs.
longScanWarning
<psalm
longScanWarning="10.0"
>
Specifies the maximum scan and analysis duration for individual files; files which take longer than the specified amount of seconds (as a floating point, so values smaller than one second are also accepted) will print out a warning to CLI (the scan will not be interrupted).
Only used in multithreaded mode, defaults to 10 seconds.
restrictReturnTypes
<psalm
restrictReturnTypes="true"
>
Emits LessSpecificReturnType when the declared return type is not as tight as
the inferred return type.
This code:
function getOne(): int // declared type: int
{
return 1; // inferred type: 1 (int literal)
}
LessSpecificReturnType - The inferred return type '1' for
getOne is more specific than the declared return type 'int'
To fix the error, you should specify the more specific type in the doc-block:
/**
* @return 1
*/
function getOne(): int
{
return 1;
}
Warning: Forcing a tighter type is not always the best course of action and
may cause unexpected results. The following code is invalid with
restrictReturnTypes="true":
class StandardCar {
/**
* @return list{'motor', 'brakes', 'wheels'}
*/
public function getSystems(): array {
return ['motor', 'brakes', 'wheels'];
}
}
class PremiumCar extends StandardCar {
/**
* @return list{'motor', 'brakes', 'wheels', 'rear parking sensor'}
*/
public function getSystems(): array {
return ['motor', 'brakes', 'wheels', 'rear parking sensor'];
}
}
ImplementedReturnTypeMismatch - The inherited return type 'list{'motor', 'brakes', 'wheels'}' for StandardCar::getSystems is different to the implemented return type for PremiumCar::getsystems 'list{'motor', 'brakes', 'wheels', 'rear parking sensor'}'
findUnusedBaselineEntry
Emits UnusedBaselineEntry when a baseline entry is not being used to suppress an issue.
findUnusedIssueHandlerSuppression
Emits UnusedIssueHandlerSuppression when a suppressed issue handler is not being used to suppress an issue.
Project settings
<projectFiles>
Contains a list of all the directories that Psalm should inspect. You can also specify a set of files and folders to ignore with the <ignoreFiles> directive. By default, ignored files/folders are required to exist. An allowMissingFiles attribute can be added for ignored files/folders than may or may not exist.
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="src/Stubs" />
</ignoreFiles>
<ignoreFiles allowMissingFiles="true">
<directory name="path-that-may-not-exist" />
</ignoreFiles>
</projectFiles>
<extraFiles>
Optional. Same format as <projectFiles>. Directories Psalm should load but not inspect.
<fileExtensions>
Optional. A list of extensions to search over. See Checking non-PHP files to understand how to extend this.
<enableExtensions>
Optional. A list of extensions to enable. By default, only extensions required by your composer.json will be enabled.
<enableExtensions>
<extension name="decimal"/>
<extension name="pdo"/>
</enableExtensions>
<disableExtensions>
Optional. A list of extensions to disable. By default, only extensions required by your composer.json will be enabled.
<disableExtensions>
<extension name="gmp"/>
</disableExtensions>
<plugins>
Optional. A list of <plugin filename="path_to_plugin.php" /> entries. See the Plugins section for more information.
<issueHandlers>
Optional. If you don't want Psalm to complain about every single issue it finds, the issueHandler tag allows you to configure that. Dealing with code issues tells you more.
<mockClasses>
Optional. Do you use mock classes in your tests? If you want Psalm to ignore them when checking files, include a fully-qualified path to the class with <class name="Your\Namespace\ClassName" />
<universalObjectCrates>
Optional. Do you have objects with properties that cannot be determined statically? If you want Psalm to treat all properties on a given classlike as mixed, include a fully-qualified path to the class with <class name="Your\Namespace\ClassName" />. By default, stdClass and SimpleXMLElement are configured to be universal object crates.
<stubs>
Optional. If your codebase uses classes and functions that are not visible to Psalm via reflection (e.g. if there are internal packages that your codebase relies on that are not available on the machine running Psalm), you can use stub files. Used by PhpStorm (a popular IDE) and others, stubs provide a description of classes and functions without the implementations.
You can find a list of stubs for common classes here.
List out each file with <file name="path/to/file.php" />. In case classes to be tested use parent classes
or interfaces defined in a stub file, this stub should be configured with attribute preloadClasses="true".
<stubs>
<file name="path/to/file.php" />
<file name="path/to/abstract-class.php" preloadClasses="true" />
</stubs>
Note: some extension stubs are already built into Psalm, and can be enabled by requiring the extension in your composer.json or by using the enableExtensions config key.
<ignoreExceptions>
Optional. A list of exceptions to not report for checkForThrowsDocblock or checkForThrowsInGlobalScope. The class tag will make Psalm ignore only instances of the specified class, while classAndDescendants will make Psalm also ignore subclasses. If an exception has onlyGlobalScope set to true, only checkForThrowsInGlobalScope is ignored for that exception, e.g.
<ignoreExceptions>
<class name="fully\qualified\path\Exc" onlyGlobalScope="true" />
<classAndDescendants name="fully\qualified\path\OtherExc" />
</ignoreExceptions>
<globals>
Optional. If your codebase uses global variables that are accessed with the global keyword, you can declare their type. e.g.
<globals>
<var name="globalVariableName" type="type" />
</globals>
Some frameworks and libraries expose functionalities through e.g. $GLOBALS[DB]->query($query).
The following configuration declares custom types for super-globals ($GLOBALS, $_GET, ...).
<globals>
<var name="GLOBALS" type="array{DB: MyVendor\DatabaseConnection, VIEW: MyVendor\TemplateView}" />
<var name="_GET" type="array{data: array<string, string>}" />
</globals>
The example above declares global variables as shown below
$GLOBALSDBof typeMyVendor\DatabaseConnectionVIEWof typeMyVendor\TemplateView
$_GETdatae.g. like["id" => "123", "title" => "Nice"]
<forbiddenFunctions>
Optional. Allows you to specify a list of functions that should emit the ForbiddenCode issue type.
<forbiddenFunctions>
<function name="var_dump" />
<function name="dd" />
</forbiddenFunctions>
<forbiddenConstants>
Optional. Allows you to specify a list of constants that should emit the ForbiddenCode issue type.
<forbiddenConstants>
<constant name="FILTER_VALIDATE_URL" />
</forbiddenConstants>
Accessing Psalm configuration in plugins
Plugins can access or modify the global configuration in plugins using singleton Psalm\Config.
$config = \Psalm\Config::getInstance();
if (!isset($config->globals['$GLOBALS'])) {
$config->globals['$GLOBALS'] = 'array{data: array<string, string>}';
}