Level up your Laravel code with PHPStan
PHPStan is a static analysis tool that helps developers identify potential bugs and issues in their code before they occur. It scans your whole codebase and looks for both obvious & tricky bugs. Even in those rarely executed if statements that certainly aren't covered by tests.
In this article, we will discuss how to set up and use PHPStan in Laravel using Larastan.
⚙️ Setting up PHPStan in Laravel using Larastan
Step 1: Install Larastan
First, we'll need to install Larastan as a development dependency in your Laravel project. You can do this by running the following command:
composer require --dev nunomaduro/larastan
Step 2: Configure PHPStan
Once we've installed PHPStan and Larastan, we'll need to create a PHPStan configuration file in your Laravel project's root directory. We can do this by creating a file named phpstan.neon
and adding the following contents:
includes:
- ./vendor/nunomaduro/larastan/extension.neon
parameters:
paths:
- app
- database
- routes
- tests
level: 6
The parameter paths
in the config file tell us which folders to analyse and the parameter level
tells us the level of phpStan rule to enforce.
Step 3: Run PHPStan
Once we have configured PHPStan, you can run it by using the following command:
./vendor/bin/phpstan analyse
📈 PHPStan Rule Levels
We can currently choose from 10 levels (0 is the loosest and 9 is the strictest) by passing -l|--level
to the analyse
command or specifying it in the phpstan.neon
file. This feature enables incremental adoption of PHPStan checks.
These are the different levels of PHPStan rules and a short description of what they check.
Level 0:
It analyses for basic checks, unknown classes, unknown functions, unknown methods called on $this
, the wrong number of arguments passed to those methods and functions, always undefined variables etc.
The above output shows errors on undefined variables
, undefined constants
, the wrong number of parameters passed
and so on.
Level 1:
It analyses for possibly undefined variables, unknown magic methods and properties on classes with __call
and __get
etc.
The above output shows errors on
unused variable use in function
,unnecessary expression calculation
and so on.
Level 2:
It analyses for unknown methods checked on all expressions (not just $this
), validating PHPDocs etc.
The above output shows errors on
undefined methods
such ascount()
and so on.
Level 3:
It analyses return types, types assigned to properties etc.
The above output shows errors on
return types
,types assigned to properties
and so on.
Level 4:
It analyses for basic dead code - always false instanceof
and other type checks, dead else
branches, unreachable code after return; etc.
The above output shows errors on
basic dead code
,unreachable code
and so on.
Level 5:
It checks for types of arguments passed to methods and functions.
The above output shows errors on
types of arguments
passed toClientListExportedNotification
inroutes.dev
.
Level 6:
It reports missing type hints.
Level 7:
It reports 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
Level 8:
It reports calling methods and accessing properties on nullable types
Level 9:
It will be strict about the mixed
type - the only allowed operation you can do with it is to pass it to another mixed
💭 Closing thoughts
If we’ve got a legacy project and we fire the PHPStan task runner at level 9, we might be overwhelmed by the results it produces. Everything is broken! To refactor, I’d suggest the following:
Set our milestones for each level identified, and start small. Then set the top level we are willing to go to when classifying “fixed the tech debt” under our own “definition of done” A good de-facto target for a legacy project is to get Rule Level 6 passing. It’s at this point where our codebase can likely transition from a state of “danger” to “correct”.
We can pump up the PHPStan checking level later and make our codebase as bug-free as possible.
You can find more information about Larastan and PHPStan in its GitHub repository. It's worth running it on your codebase, and you'll probably find bugs you looked over.
Subscribe to my newsletter
Read articles from Sandip Shrestha directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sandip Shrestha
Sandip Shrestha
I am a Full stack Software Engineer and also a hobbyist writer who writes about Software Development and its allied intricacies. I hold on to my methods loosely, embrace flexibility & modularity and believe we can always grow.