Using Static Analysis in Laravel: A Guide to Starting with PHPStan in Your Project
It's always beneficial to explore ways to improve code, particularly in maintaining consistent formatting and readability, especially in larger projects. That's why it's crucial to consider using static analysis in your project if you haven't already.
Static analysis tool in PHP is a game-changer for code quality and readability. These tools are like having an extra pair of eyes that meticulously scan your code, pointing out any errors, typos, or even potential issues that could turn into bigger problems down the line. This is super handy because, let's face it, mistakes happen more often than we'd like to admit.
PHPStan is one of the most popular and free static analysis tools. So in this post, I just want to briefly provide a step-by-step guide on how to use PHPStan in a Laravel project. I'm hoping this will be particularly useful for those who are new to this topic.
1. Install PHP Stan
composer require phpstan/phpstan --dev
2. Install Larastan
composer require nunomaduro/larastan --dev
Larastan is specifically designed for Laravel projects. It's essentially an extension of PHPStan. By using Larastan in your Laravel projects, you're essentially adding an extra layer of quality control. It helps ensure that your code is not just error-free, but also adheres to good coding practices specific to Laravel. It provides the static analysis tool with an understanding of most of Laravel's beautiful magic.
3. Install Laravel IDE Helper
composer require --dev barryvdh/laravel-ide-helper
Laravel IDE Helper Generator for Laravel is package to generate PHPDocs, mostly for Laravel models.
PHPDocs play a significant role in describing code to static analysis tools. Therefore, it's highly beneficial to leverage this package and ensure your models are thoroughly documented with essential PHPDocs.
It also generates helper files that enable your IDE to provide accurate autocompletion. Generation is done based on the files in your project, so they are always up-to-date.
4. Configure Laravel IDE Helper
Let’s publish configuration file of package to project config directory.
php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider" --tag=config
After this command, you may find ide-helper.php file in config folder.
Changing any of configuration there is optionally, but I want to ended up with one thing there:
'model_locations' => [
'app',
],
You may adjust locations of your models. For example, if some of your models are located in your core package in vendor, you may just provide exact location here, like this:
'model_locations' => [
'app',
'vendor/labrodev/filter-components/src/Models'
],
5. Generate Laravel IDE Helper files
Generate ide-helper file
php artisan ide-helper:generate
This command is used to generate a file that provides correct PHPDoc annotations for all Facade classes. This helps integrated development environments (IDEs) understand the Laravel Facades better, thereby improving auto-completion and code analysis (and static analysis) features.
As a result, you may find generated file _ide_helper.php in root of your project.
Add \Eloquent mixin
php artisan ide-helper:eloquent
This command adds docblock mixin to /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:
@mixin \Eloquent
This annotation tells the IDE that the methods from the Eloquent class are available in the model, even though they're not explicitly defined there. This enables the IDE to offer code completion, function lookup, and other helpful insights for Eloquent methods when you're working on your models. And again, it helps to better understanding of code and static analysis.
Generate PHPDocs for models
There is a 2 ways of adding PHPDocs in your model.
to add PHPDocs to each Model class directly
to generate separate files with PHPDocs for each Model class with mixin alias and to put only this alias to each Model file.
From my perspective, the second approach is much better because it avoids overloading models with lengthy PHPDoc blocks that don't add any functional value. Instead, everything necessary for static analysis is kept in one separate, specific file.
To generate PHPDocs in a separate file and add only mixins to the Model classes, we need to use the --write-mixin
option in the command. Conversely, to write PHPDocs directly into Model classes, use the --write
option.
More information specifically related to this command you may find here.
php artisan ide-helper:models --write-mixin
As result you may find generated file _ide_helper_models.php with all PHPDocs related to each model.
And you may check your Model classes, there you may find mixin with alias to _ide_helper_models classes. Something like this:
/**
* @mixin IdeHelperYourModel
*/
Generare PHPStorm meta information
It’s optionally and could give benefits mostly for your IDE environment if IDE is PHP Storm.
php artisan ide-helper:meta
As result, you may find .phpstorm.meta.php file at the root of your project.
6. Create PHPStan configuration file
Let’s create phpstan.neon file in root of your project. And adjust configuration of PHPStan.
includes:
- ./vendor/nunomaduro/larastan/extension.neon
parameters:
level: 9
paths:
- app
scanFiles:
- _ide_helper.php
- _ide_helper_models.php
- .phpstorm.meta.php
checkGenericClassInNonGenericObjectType: false
Let’s break up what’s going on in this configuration file.
includes: specifies that the Larastan configuration will include settings from the extension.neon
file found in the Larastan package. This file typically contains Larastan-specific configurations and is essential for integrating Larastan's static analysis capabilities into your project.
level: 9 : This sets the strictness level of the analysis. In PHPStan (and Larastan by extension), the levels range from 0 (most lenient) to 9 (most strict). A higher level means the tool will perform a more thorough analysis, catching more potential issues.
paths: this tells Larastan to analyze the files in the app directory of your Laravel project. It's where most of your application's core logic resides, so it's crucial for static analysis.
scanFiles: files are added to the scan list to ensure that Larastan understands your IDE helpers and any custom meta-information provided by PHPStorm (or other IDEs). It helps in making the analysis more accurate, especially for Laravel-specific features and helpers.
checkGenericClassInNonGenericObjectType : this option, when set to false, instructs Larastan to not report errors related to the usage of generic classes in non-generic object types.
7. Define composer command to run PHP Stan analysis
Let’s go to composer.json and adjust “scripts” part to define command for running PHP Stan from composer.
"scripts": {
"phpstan": "vendor/bin/phpstan analyse"
},
So now we may use this command in console to run PHP Stan:
composer phpstan
Now, you may enjoy results of static analysis and investigate reports with errors provided by PHP Stan.
Wish you happy coding and green reports in PHP Stan.
Thanks you for attention.