Result cache

Even with the improvements achieved by parallel analysis, there was one more opportunity to achieve an order-of-magnitude speed-up.

One idea that’s easy to come up with is to analyse only changed files. You might have seen a suggestion to run PHPStan like this:

# Don't do this!

git diff --name-only origin/master..HEAD -- *.php | xargs vendor/bin/phpstan analyse

First problem with this approach is that by changing one file, we can break a different file. For example if we add a method to an interface we need to reanalyse all the classes that implement the interface. We might miss out on real errors with this naïve approach.

Instead, we need to build a tree of dependencies between the files. So when we detect that A.php was changed, we analyse A.php + all the files calling or otherwise referencing all the symbols in A.php .

Second problem is that even if we successfully mark all the right files that need to be reanalysed, we won’t see the errors from the remaining files. In order for users to not even notice they’re really analysing only a subset of files, we need to cache the list of errors from past analyses.

Hence the name: result cache.

We’ve been testing this feature at my day job @ Slevomat for the past year and it’s really solid. It’s now also enabled by default in the latest PHPStan release.

The cache gets invalidated, and PHPStan runs on all files again, if one or more of these items changed since the most recent analysis:

PHPStan version

PHP version

Loaded PHP extensions

composer.lock contents (3ʳᵈ party dependencies were updated)

Contents of the project’s PHPStan configuration file

Contents of included stub files for overriding 3ʳᵈ party PHPDocs

Used rule level (using --level or -l on the command line)

or on the command line) Analysed paths

Especially the last item now makes the practice using git diff counter-productive. The list of analysed paths needs to remain stable for the result cache to be used. So the best practice is to always run PHPStan on the whole project.

If you want to run PHPStan without the result cache being used for some reason, you can use the new clear-result-cache command:

vendor/bin/phpstan clear-result-cache -c phpstan.neon && \

vendor/bin/phpstan analyse -c phpstan.neon -l 8 src/ tests/

I’m really excited about these improvements and can’t wait till you try them out! I’m looking forward to your feedback.