Learning from open source PHP projects - Part 2 - Static analysis
Let's check our 5 open source projects again and look at what they use:
- Flowphp uses PHPStan
- psl uses Psalm
- BetterReflection uses Psalm and PHPStan
- EventSauce uses PHPStan
- Tempest Framework uses PHPStan
So, in our very little group, we can see that PHPStan is almost everywhere. But we also see that Psalm is far from being out of the radar yet.
PHPStan
Let's compare the PHPStan configurations first. The strictness level can go from 0 (very limited checks) to 9 for PHPStan v1, and up to 10 for PHPStan v2 (highest amounts of checks). If you play videogames, it's a bit like choosing your difficulty level. But the more difficult it is, the more confident you will be in your code. At the time of writing, here are the levels for each projects:
- EventSauce: PHPStan v1 - Level 9
- Flow: PHPStan v2 - Level 8
- BetterReflection: PHPStan v2 - Level 6
- Tempest: PHPStan v2 - Level 5
My initial thought was that probably the oldest projects in the list would use lowest levels of checks, but that is not necessarily the case. EventSauce for example was started in 2017 and has the highest level. While Tempest is a relatively new project and uses level 5. So this might indicate also that there might be some preferences from the developing team to keep some flexibility in the pace of development.
Well, let's see what we can learn by looking at those configuration files.
Tempest's configuration has an interesting feature I didn't know about, that comes from a package: disallowedFunctionCalls
. Within Tempest, they use it to prohibit usage of methods such as exec()
, eval()
, phpinfo()
. Quite useful especially when you receive code from people who might be doing mischievous things with your project. On top of this dd()
, dump()
and var_dump()
are also prohibited. Quite the time-saver, has I cannot recall the amount of time I had to ask remains of variable dumps to be removed from a pull request. Better let PHPStan prohibit that for us. Definitely something I'll reuse in other projects.
Another interesting feature used by Tempest is the phpat package. It provides an easy to use API to define authorized relationship between classes in the project. Readers being familiar with architecture definitions of a project know all too well that as soon as they turn their eyes, other developers will happily break the rules, leaving the project in architecture limbo in no time.
BetterReflection is using a package for PHPStan and PHPUnit called phpstan-phpunit
. It allows PHPStan to interpret mock objects created by PHPUnit as an intersection of the object that is mocked and the PHPUnit_Framework_MockObject_MockObject
class.
All projects have exclusion filters, so there are always a few cases where you want these warnings to be silenced. Most notably the test classes seems to be muted a lot.
Psalm
Psalm also has error levels, and it's in reverse order compared to PHPStan: level 1 is the strictest, while level 8 is the least strict. Both BetterReflection and psl use level 1.
Just like PHPStan, Psalm allows the use of a baseline, so it can easily be integrated into an existing project.
The configuration files of both projects do not learn us much besides little tweaks linked to the particularities of the codebase.