PHP: PHPStan

Antonio Silva - Oct 10 '23 - - Dev Community

PHPStan - PHP Static Analysis Tool

PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code can be checked before you run the actual line.

PHPStan requires PHP >= 7.2. You have to run it in environment with PHP 7.x but the actual code does not have to use PHP 7.x features. (Code written for PHP 5.6 and earlier can run on 7.x mostly unmodified.)

PHPStan works best with modern object-oriented code. The more strongly-typed your code is, the more information you give PHPStan to work with.

Installation

To start performing analysis on your code, require PHPStan in Composer:

composer require --dev phpstan/phpstan
Enter fullscreen mode Exit fullscreen mode

Composer will install PHPStan’s executable in its bin-dir which defaults to vendor/bin.

First run

To let PHPStan analyse your codebase, you have to use the analyse command and point it to the right directories.

So, for example if you have your classes in directories src and tests, you can run PHPStan like this:

vendor/bin/phpstan analyse --level [0-9] src tests
Enter fullscreen mode Exit fullscreen mode

output

Rule Levels

If you want to use PHPStan but your codebase isn’t up to speed with strong typing and PHPStan’s strict checks, you can currently choose from 10 levels (0 is the loosest and 9 is the strictest) by passing -l|--level to the analyse command.

vendor/bin/phpstan analyse -l 6 src tests
Enter fullscreen mode Exit fullscreen mode

The default level is 0. Once you specify a configuration file, you also have to specify the level to run.

Here’s a brief overview of what’s checked on each level. Levels are cumulative - for example running level 5 also gives you all the checks from levels 0-4.

0.basic checks, unknown classes, unknown functions, unknown methods called on $this, wrong number of arguments passed to those methods and functions, always undefined variables.

1.possibly undefined variables, unknown magic methods and properties on classes with __call and __get.

2.unknown methods checked on all expressions (not just $this), validating PHPDocs.

3.return types, types assigned to properties.

4.basic dead code checking - always false instanceof and other type checks, dead else branches, unreachable code after return; etc.

5.checking types of arguments passed to methods and functions.

6.report missing typehints.

7.report partially wrong union types - if you call a method that only exists on some types in a union type, level 7 starts to report that; other possibly incorrect situations.

8.report calling methods and accessing properties on nullable types.

9.be strict about the mixed type - the only allowed operation you can do with it is to pass it to another mixed.

Command Line Usage

PHPStan’s executable file is installed in Composer’s bin-dir which defaults to vendor/bin.

Analysing code

To analyse your code, run the analyse command. Exit code 0 means there are no errors.

vendor/bin/phpstan analyse [options] [<paths>...]
Enter fullscreen mode Exit fullscreen mode

As <paths> you can pass one or multiple paths to PHP files or directories separated by spaces.

To find the options here.

Config Reference

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
       - file.php
Enter fullscreen mode Exit fullscreen mode

Config file

A config file can be passed to the phpstan executable using the -c|--configuration option:

vendor/bin/phpstan analyse -c phpstan.neon
Enter fullscreen mode Exit fullscreen mode

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.

Analysed files

You can save some keystrokes each time you run PHPStan by moving the analysed paths to the config file:

parameters:
    paths:
      - src
      - tests
Enter fullscreen mode Exit fullscreen mode

Relative paths in the paths key are resolved based on the directory of the config file is in.

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.

parameters:
    excludePaths:
        - tests/*/data/*
Enter fullscreen mode Exit fullscreen mode

This is a shortcut for:

parameters:
    excludePaths:
        analyseAndScan:
             - tests/*/data/*
Enter fullscreen mode Exit fullscreen mode

If your project’s directory structure mixes your own code 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

By default, PHPStan analyses only files with the .php extension. To include other extensions, use the fileExtensions key:

parameters:
    fileExtensions:
        - php
        - module
        - inc
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .