Ondřej Mirtes shares the idea behind the creation of PHPStan – a static analysis tool for PHP:
Compiled languages need to know about the type of every variable, return type of every method etc. before the program runs. This is why the compiler needs to make sure that the program is “correct” and will happily point out to you these kinds of mistakes in the source code, like calling an undefined method or passing a wrong number of arguments to a function. The compiler acts as a first line of defense before you are able to deploy the application into production.
On the other hand, PHP is nothing like that. If you make a mistake, the program will crash when the line of code with the mistake is executed. When testing a PHP application, whether manually or automatically, developers spend a lot of their time discovering mistakes that wouldn’t even compile in other languages, leaving less time for testing actual business logic.
I’d like to change that.
This made sense to me, so I rushed to the repository. I have quite a few projects to try this on. I hurried so much that I didn’t pay attention to the important notes (aka prerequisities). These are:
PHPStan requires PHP 7.0. You have to run it in environment with PHP 7 but the actual code does not have to use PHP 7 features. (Code written for PHP 5.6 and earlier can run on 7 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.
Properly annotated and typehinted code (class properties, function and method arguments, return types) helps not only static analysis tools but also other people that work with the code to understand it.
Erm … if I had properly annotated and typehinted code, which is nicely organized into objects, I think, I wouldn’t need PHPStan as much as I need it now. Anybody can analyze beautiful code. Try figuring out what’s going on in a WordPress theme with 150 PHP files, split into classes, functions and chunks of unmaintainable code. That’s where I wanted PHPStan to help me.
But OK. Let’s see what it can do. Gladly, my laptop already runs PHP 7 – here is a good first use for it.
Intstalling PHPStan with composer was easy. All I had to do was resolve the nikic/php-parser dependency conflict between PHPStan and Sami, which is our source code documentation tool of choice (the newer version uses a much more recent version of the PHP Parser, so it wasn’t rocket science).
Once installed, a simple “vendor/bin/phpstan analyse ./src” command produced a report with a few issues. Most of those were false positives, which can be fixed with a bit of PHPStan configuration. But a few real problems that were found, were indeed bits that sneaked through our automated and manual testing. For example:
------ ---------------------------------
Line src/Shell/EmailShell.php
------ ---------------------------------
37 Return typehint of method App\Shell\EmailShell::getOptionParser() has invalid type App\Shell\ConsoleOptionParser.
------ ---------------------------------
I don’t think we’ll use PHPStan across all our code base just yet. It’ll be too noisy for some projects. And the PHP 7 requirement is not that easy to satisfy just yet. But maybe sometime next year, once we finalize our move to PHP 7, I will integrate it into our automatic testing process.
All in all, it’s quite a useful tool and much needed for larger code bases.