Config Reference
Getting started?
This page is about all the configuration options PHPStan has. If you want to learn how to start using PHPStan, head to Getting Started instead.
NEON format #
PHPStan uses configuration format called NEON. It’s very similar to YAML so if you’re familiar with it, you can also write NEON.
This is how a possible example of a config file can look like:
parameters:
level: 6
paths:
- src
- tests
Config file #
A config file can be passed to the phpstan
executable using the -c|--configuration
option:
vendor/bin/phpstan analyse -c phpstan.neon
When using a config file, you have to pass the --level|-l
option to analyse
command (default value 0
does not apply here), or provide it as a level
parameter in the config file itself. Learn more about other command line options »
If you do not provide a config file explicitly, PHPStan will look for files named phpstan.neon
, phpstan.neon.dist
, or phpstan.dist.neon
in the current directory.
The resolution priority is as such:
- If config file is provided as a command line option, it will be used.
- Otherwise, if
phpstan.neon
exists in the current working directory, it will be used. - Otherwise, if
phpstan.neon.dist
exists in the current working directory, it will be used. - Otherwise, if
phpstan.dist.neon
exists in the current working directory, it will be used. - If none of the above is true, no config will be used.
The usual practice is to have phpstan.neon.dist
or phpstan.dist.neon
under version control, and allow the user to override certain settings in their environment (on their own computer or on a continuous integration server) by creating phpstan.neon
that’s present in .gitignore
file. See Multiple files for more details:
Multiple files #
The NEON format supports an includes
section to compose the final configuration from multiple files. Let’s say the phpstan.neon.dist
project config file looks like this:
parameters:
level: 6
paths:
- src
- tests
If the user doesn’t have certain PHP extensions, wants to ignore some reported errors from the analysis, and to disable parallel CPU processing, they can create phpstan.neon
file with this content:
includes:
- phpstan.neon.dist
parameters:
ignoreErrors:
- '#Function pcntl_open not found\.#'
parallel:
maximumNumberOfProcesses: 1
Relative paths in the includes
section are resolved based on the directory of the config file is in. So in this example, phpstan.neon.dist
and phpstan.neon
are next to each other in the same directory.
includes
can also reference PHP files that can be used to define dynamic configurations, see ignore-by-php-version.neon.php and phpstan.neon as examples.
Ignoring errors #
Learn more about ignoring errors in the user guide.
Related config keys: ignoreErrors
, reportUnmatchedIgnoredErrors
.
Discovering symbols #
Learn more about discovering symbols in the user guide.
Related config keys: scanFiles
, scanDirectories
.
Bootstrap #
If you need to initialize something in PHP runtime before PHPStan runs (like your own autoloader), you can provide your own bootstrap files:
parameters:
bootstrapFiles:
- phpstan-bootstrap.php
Relative paths in the bootstrapFiles
key are resolved based on the directory of the config file is in.
Caching #
By default, PHPStan stores its cache files in sys_get_temp_dir() . '/phpstan'
(usually /tmp/phpstan
). You can override this by setting the tmpDir
parameter:
parameters:
tmpDir: tmp
Relative path in the tmpDir
key is resolved based on the directory of the config file is in. In this example PHPStan cache will be stored in tmp
directory that’s next to the configuration file.
Analysed files #
PHPStan accepts a list of files and directories on the command line:
vendor/bin/phpstan analyse -c src tests
You can save some keystrokes each time you run PHPStan by moving the analysed paths to the config file:
parameters:
paths:
- src
- tests
Relative paths in the paths
key are resolved based on the directory of the config file is in.
If you provide analysed paths to PHPStan on the command line and in the config file at the same time, they are not merged. Only the paths on the command line will be used.
You should only analyse files with the code you’ve written yourself. There’s no need to analyse the vendor
directory with 3rd party dependencies because it’s not in your power to fix all the mistakes made by the developers you don’t work with directly.
Yes, PHPStan needs to know about all the classes, interfaces, traits, and functions your code uses, but that’s achieved through discovering symbols, not by including the files in the analysis.
If your codebase contains some files that are broken on purpose (e. g. to test behaviour of your application on files with invalid PHP code), you can exclude them using the excludePaths
key. Each entry is used as a pattern for the fnmatch()
function.
parameters:
excludePaths:
- tests/*/data/*
This is a shortcut for:
parameters:
excludePaths:
analyseAndScan:
- tests/*/data/*
If your project’s directory structure mixes your own code (the one you want to analyse and fix bugs in) and third party code (which you’re using for discovering symbols, but don’t want to analyse), the file structure might look like this:
├── phpstan.neon
└── src
├── foo.php
├── ...
└── thirdparty
└── bar.php
In this case, you want to analyse the whole src
directory, but want to exclude src/thirdparty
from analysing. This is how to configure PHPStan:
parameters:
excludePaths:
analyse:
- src/thirdparty
Additionally, there might be a src/broken
directory which contains files that you don’t want to analyse nor use for discovering symbols. You can modify the configuration to achieve that effect:
parameters:
excludePaths:
analyse:
- src/thirdparty
analyseAndScan:
- src/broken
By default, PHPStan analyses only files with the .php
extension. To include other extensions, use the fileExtensions
key:
parameters:
fileExtensions:
- php
- module
- inc
Rule level #
Learn more about rule levels in the user guide.
Instead of using the CLI option --level
, you can save some keystrokes each time you run PHPStan by moving the desired level to the config file:
parameters:
level: 6
Custom ruleset #
PHPStan requires you to specify a level to run which means it will choose the enforced rules for you. If you don’t want to follow the predefined rule levels and want to create your own ruleset, tell PHPStan to not require a level by setting customRulesetUsed
to true:
parameters:
customRulesetUsed: true
You can then choose your own ruleset by copying parts of the level configuration files from PHPStan sources, or include your own custom rules.
Bleeding edge #
Bleeding edge offers a preview of the next major version. When you enable Bleeding edge in your configuration file, you will get new rules, behaviour, and bug fixes that will be enabled for everyone later when the next PHPStan’s major version is released.
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon
Learn more about bleeding edge.
Solving undefined variables #
Learn more about solving undefined variables in Writing PHP Code.
Related config keys: earlyTerminatingMethodCalls
, earlyTerminatingFunctionCalls
.
Universal object crates #
Classes without predefined structure are common in PHP applications. They are used as universal holders of data - any property can be set and read on them. Notable examples include stdClass
, SimpleXMLElement
(these are enabled by default), objects with results of database queries etc. Use universalObjectCratesClasses
key to let PHPStan know which classes with these characteristics are used in your codebase:
parameters:
universalObjectCratesClasses:
- Dibi\Row
- Ratchet\ConnectionInterface
See also object shape PHPDoc type for a better alternative that lets you describe types of properties of such objects.
Constants #
Learn more about letting PHPStan know about your global constants in the user guide.
Sometimes your constants can have different values in different environments, like DATABASE_ENGINE
that can have different values like mysql
or pgsql
. To let PHPStan know that the value of the constant can be different, and prevent errors like Strict comparison using === between 'pgsql' and 'mysql' will always evaluate to false.
, add the constant name to dynamicConstantNames
key:
parameters:
dynamicConstantNames:
- DATABASE_ENGINE
- Foo::BAR_CONSTANT # class constants are also supported
Stub files #
Learn more about stub files in the user guide.
Related config key: stubFiles
.
Stricter analysis #
Existing outside of rule levels there are additional parameters affecting analysis result you can tune.
polluteScopeWithLoopInitialAssignments
#
default: true
(strict-rules sets it to false
)
example: with true
, with false
When set to false
it prevents reading variables set in for
loop initial statement and while
loop condition after the loop.
polluteScopeWithAlwaysIterableForeach
#
default: true
(strict-rules sets it to false
)
example: with true
, with false
When set to false
it prevents reading key and value variables set in foreach when iterating over a non-empty array.
polluteScopeWithBlock
#
default: true
(strict-rules sets it to false
)
example: with true
, with false
When set to false
it prevents reading key and value variables set in a separate code block in {...}
.
checkExplicitMixedMissingReturn
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports code paths with missing return
statement in functions and methods with @return mixed
PHPDoc.
checkFunctionNameCase
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports function and method calls with incorrect name case.
checkInternalClassCaseSensitivity
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports references to built-in classes with incorrect name case.
reportMaybesInMethodSignatures
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports violations of parameter type contravariance and return type covariance. By default, PHPStan only reports completely incompatible types in signatures, see this example.
reportMaybesInPropertyPhpDocTypes
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports violations of property type invariance. By default, PHPStan only reports completely incompatible PHPDoc typescheckInternalClassCaseSensitivity, see this example.
reportStaticMethodSignatures
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports violations of parameter type contravariance and return type covariance in static methods.
checkTooWideReturnTypesInProtectedAndPublicMethods
#
default: false
When set to true
, it reports return typehints that could be narrowed down because some of the listed types are never returned from a public or protected method. For private methods PHPStan does this by default.
public function doFoo(): ?string
{
// Method Foo::doFoo() never returns null so it can be removed from the return typehint.
return 'str';
}
checkUninitializedProperties
#
default: false
When set to true
, it reports properties with native types that weren’t initialized in the class constructor.
// "Class has an uninitialized property $foo. Give it default value or assign it in the constructor."
private int $foo;
public function setFoo(int $foo): void
{
$this->foo = $foo;
}
checkDynamicProperties
#
default: false
(strict-rules sets it to true
)
example: with false
, with true
When set to true
, it reports use of dynamic properties as undefined.
rememberPossiblyImpureFunctionValues
#
default: true
By default, PHPStan considers all functions that return a value to be pure. That means that second call to the same function in the same scope will return the same narrowed type:
public function getName(): string
{
return $this->name;
}
if ($this->getName() === 'Foo') {
echo $this->getName(); // still 'Foo'
}
This is a sane default in case of getters but sometimes we have a function that can return different values based on a global state like a random number generator, database, or time.
public function getRandomNumber(): int
{
return rand();
}
if ($this->getRandomNumber() === 4) {
echo $this->getRandomNumber(); // it's not going to be 4 but PHPStan will think it is
}
You can mark getRandomNumber()
with /** @phpstan-impure */
but if you have many functions like this in your codebase and don’t want to assume functions return the same value when called multiple times, you can set rememberPossiblyImpureFunctionValues
to false
:
parameters:
rememberPossiblyImpureFunctionValues: false
checkImplicitMixed
#
default: false
When set to true
, PHPStan is strict about values with an unspecified (implicit mixed
) type. It enables the same checks for values with no type specified that rule level 9 enables for explicitly specified mixed
type values.
checkBenevolentUnionTypes
#
default: false
PHPStan defines benevolent union types, such as array-key
. Benevolent unions aren’t checked strictly even at the highest level:
public function requireInt(int $value): void {}
public function requireString(string $value): void {}
/**
* @param array-key $value1 // array-key is a benevolent union (int|string)
* @param int|string $value2
*/
public function test($value1, int|string $value2): int
{
$this->requireInt($value1); // No error
$this->requireString($value1); // No error
$this->requireInt($value2); // Error
$this->requireString($value2); // Error
}
Enable stricter analysis of benevolent union types with the checkBenevolentUnionTypes
option (needs level 7 or higher):
parameters:
checkBenevolentUnionTypes: true
reportPossiblyNonexistentGeneralArrayOffset
#
By default PHPStan does not report possibly nonexistent offset on general arrays:
/**
* @param array<string, int> $array
*/
public function doFoo(array $array): int
{
return $array['foo'];
}
By setting reportPossiblyNonexistentGeneralArrayOffset
to true
this will be reported as an error. This option has effect on rule level 7 and up.
reportPossiblyNonexistentConstantArrayOffset
#
By default PHPStan does not report possibly nonexistent offset on array shapes:
public function doFoo(string $s): void
{
$a = ['foo' => 1];
echo $a[$s];
}
By setting reportPossiblyNonexistentConstantArrayOffset
to true
this will be reported as an error. This option has effect on rule level 7 and up.
reportAlwaysTrueInLastCondition
#
default: false
By default PHPStan does not report always true last condition in a series of elseif
branches and match expression arms:
// $o is A|B
if ($o instanceof A) {
// ...
} elseif ($o instanceof B) { // "Instanceof between B and B will always evaluate to true." IS NOT reported
// ...
}
By setting reportAlwaysTrueInLastCondition
to true
the error in elseif
will be reported.
reportWrongPhpDocTypeInVarTag
#
default: false
(strict-rules sets it to true
)
example: with true
, with false
By default PHPStan reports wrong type in @var
tag only for native types on the right side of =
. With reportWrongPhpDocTypeInVarTag
set to true
it will consider PHPDoc types too.
This effectively means that inline @var
cast can only be used to narrow down original types. PHPStan offers many utilities to use instead:
- Conditional return types
@phpstan-assert
- Generics
- Stub files for overriding 3rd party PHPDocs
- Dynamic return type extensions
reportAnyTypeWideningInVarTag
#
default: false
This option strictens checks used in reportWrongPhpDocTypeInVarTag
. It strictly disallows any type widening. Compared to default behaviour, it disallows array key widening in inline PHPDoc @var
tags, so those would get reported:
list<int>
=>array<int>
array<int, int>
=>array<int>
checkMissingOverrideMethodAttribute
#
default: false
When set to true
, PHPStan reports missing #[\Override]
attribute above methods that override a method coming from their parent classes, implemented interfaces, or abstract method from a used trait.
class Foo
{
public function doFoo(): void
{
}
}
class Bar extends Foo
{
public function doFoo(): void
{
// missing #[\Override] above this method
}
}
Please note that aside from setting this config parameter to true
, you also need to set phpVersion
to 80300
or higher. If you’re not changing phpVersion
in your config, make sure you’re running PHPStan with PHP 8.3 or newer.
Exceptions #
Advanced exceptions-related rules are available. Read this article for more details ».
Related config keys: exceptions.implicitThrows
, exceptions.uncheckedExceptionRegexes
, exceptions.uncheckedExceptionClasses
, exceptions.checkedExceptionRegexes
, exceptions.checkedExceptionClasses
, exceptions.reportUncheckedExceptionDeadCatch
, exceptions.check.missingCheckedExceptionInThrows
, exceptions.check.tooWideThrowType
Vague typehints #
If you use callables, you might find that callable
or \Closure
is too vague for your liking. For example, PHPStan won’t complain if you pass callable(int) : void
to callable
, but it will complain if you pass callable(int) : void
to callable(string) : void
. So, being specific with callable signatures helps PHPStan find more bugs.
However, by default PHPStan won’t complain if you don’t specify a signature for a callable or closure.
You can make PHPStan require that callable signatures are specified with PHPStan’s callable PHPDoc syntax by setting the checkMissingCallableSignature
key to true
(disabled by default):
parameters:
checkMissingCallableSignature: true
This also requires level 6 and up.
Type aliases #
Learn more about type aliases in Writing PHP Code.
Related config key: typeAliases
.
PHPStan Pro #
You can override the DNS servers PHPStan Pro uses to download the application:
parameters:
pro:
dnsServers:
- '8.8.8.8'
By default, PHPStan Pro stores its files in sys_get_temp_dir() . '/phpstan-fixer'
. If that does not work for you for example because of multi-user environment, you can change this setting. You can also take advantage of environment variables:
parameters:
pro:
tmpDir: tmp
Relative path in the pro.tmpDir
key is resolved based on the directory of the config file is in. In this example PHPStan cache will be stored in tmp
directory that’s next to the configuration file.
Parallel processing #
PHPStan runs in multiple threads by default, taking advantage of multiple cores in your CPU. It uses a formula to figure out how many child processes to spawn. The child processes are given “jobs” - each job represents a batch of a certain number of files to process. The inputs to the formula are:
- Auto-detected number of logical CPU cores on your system. If you have 8 physical cores and hyper-threading-enabled CPU, you have 16 logical CPU cores.
- Maximum number of desired spawned processes, to prevent CPU hogging of the whole system if it’s resource-constrained. (
maximumNumberOfProcesses
) - Minimum number of jobs per process. Process is spawned only if it will process at least 2 jobs by default. (
minimumNumberOfJobsPerProcess
) - Job size - how many files are analysed in a single batch (
jobSize
) - Number of analysed files - it’s different each time because of how your codebase changes, and also thanks to the result cache.
These variables can be changed in the configuration. Here are the defaults:
parameters:
parallel:
jobSize: 20
maximumNumberOfProcesses: 32
minimumNumberOfJobsPerProcess: 2
You might encounter this error message when running PHPStan:
Child process timed out after 60 seconds. Try making it longer with
parallel.processTimeout
setting.
This can happen when a single job takes longer than the set timeout. It prevents PHPStan from running indefinitely when something unexpected occurs. In case of large files, it might be normal that the analysis of some of them takes longer. You can make the timeout longer in the configuration:
parameters:
parallel:
processTimeout: 300.0
To disable parallel processing altogether, set maximumNumberOfProcesses
to 1
:
parameters:
parallel:
maximumNumberOfProcesses: 1
Parallel processing is also disabled when running with --debug
. [1]
Clickable editor URL #
You can configure PHPStan to show clickable editor URL leading to the file and line with error in the default table
error formatter. Learn more
Related config key: editorUrl
Miscellaneous parameters #
phpVersion
#
default: null
(current PHP version is used)
If you want to analyse a codebase as if it was written for a different PHP version than you’re currently running, change the phpVersion
parameter:
parameters:
phpVersion: 70400 # PHP 7.4
Since PHPStan 2.0 you can define a range of minimum and maximum phpVersion
parameter:
parameters:
phpVersion:
min: 80103 # PHP 8.1.3
max: 80304 # PHP 8.3.4
PHPStan will automatically infer the config.platform.php
version from the last composer.json
file it can find, if not configured in the PHPStan configuration file.
inferPrivatePropertyTypeFromConstructor
#
default: false
When set to true
, it doesn’t require typehints for properties if the types can be inferred from constructor injection:
private $foo; // PHPStan infers $foo to be Foo
public function __construct(Foo $foo)
{
$this->foo = $foo;
}
treatPhpDocTypesAsCertain
#
default: true
example: with true
, with false
PHPStan by default doesn’t differentiate between PHPDoc and native types. It considers them both as certain.
This might not be what you want in case you’re writing a library whose users might pass a wrong argument type to a function. Setting treatPhpDocTypesAsCertain
to false
relaxes some of the rules around type-checking.
tips
#
If you want to turn off a tip that PHPStan shows, you can do this in the tips section:
parameters:
tips:
treatPhpDocTypesAsCertain: true
tipsOfTheDay
#
default: true
From time to time, PHPStan shows “💡 Tips of the Day” at the end of a successful analysis. You can turn this off by setting tipsOfTheDay
key to false
.
errorFormat
#
default: null
If you want to change the default error formatter, you can specify that using:
parameters:
errorFormat: json
additionalConstructors
#
default: []
If you want to avoid errors caused by writing to readonly properties outside of constructors, configure additionalConstructors
to specify methods to treat as constructors:
parameters:
additionalConstructors:
- PHPUnit\Framework\TestCase::setUp
This is useful when injecting dependencies with setter methods, or when writing “wither” methods on immutable objects.
Environment variables #
Parameters can reference environment variables:
parameters:
tmpDir: %env.PHPSTAN_TMP_DIR%
This example assumes you’ve set an environment variable called PHPSTAN_TMP_DIR
before running PHPStan:
export PHPSTAN_TMP_DIR=/home/ondrej/phpstan-temp
Expanding paths #
There are two predefined parameters usable to expand in config parameters that represent paths:
%rootDir%
- root directory where PHPStan resides (i.e.vendor/phpstan/phpstan
in Composer installation)%currentWorkingDirectory%
- current working directory where PHPStan was executed
These are no longer very useful as all relative paths in config parameters are resolved based on the directory of the config file is in, resulting in a short and concise notation.
Consider this directory structure:
app/
model/
ui/
Foo.php
build/
phpstan.neon
src/
tests/
vendor/
To reference the Foo.php
file from phpstan.neon
, you can simply use ../app/ui/Foo.php
.
To reference the Foo.php
involving %rootDir%
, you’d have to use %rootDir%/../../../app/ui/Foo.php
which isn’t really nice.
Custom parameters #
When developing custom PHPStan extensions, you might need a custom config parameter to provide customization to the user.
PHPStan does not allow unknown parameters to be present in the config in order to prevent typos. Any new parameter also needs to be added to the top-level parametersSchema
section of the config file.
The schema is defined using nette/schema library. Definition of some of the built-in PHPStan parameters looks like this:
parametersSchema:
earlyTerminatingMethodCalls: arrayOf(listOf(string()))
earlyTerminatingFunctionCalls: listOf(string())
memoryLimitFile: string()
staticReflectionClassNamePatterns: listOf(string())
dynamicConstantNames: listOf(string())
customRulesetUsed: bool()
If your parameters are nested arrays, you need to use the structure
keyword:
parametersSchema:
symfony: structure([
container_xml_path: schema(string(), nullable())
constant_hassers: bool()
console_application_loader: schema(string(), nullable())
])
Although you don’t want to always run PHPStan with this option. ↩︎