We've finished the functionality but also need to "cleanup" our code. And we will use two different tools for that.
This tool helps identify various code styling issues like unused imports we left, line/symbol spaces here and there, etc.
Laravel Pint is an official first-party tool built on top of PHP-CS-Fixer and makes it simple to ensure that your code style stays clean and consistent.
To fix your code styling with Pint, you only need to install it with Composer and run its command in Terminal. That's it. Let's do that and see what Pint will say about the errors in our code.
Notice: Pint will immediately make changes to your files. But you can roll them back if you want or run Pint with the --test
option.
composer require laravel/pint --dev
And then we just run this in Terminal:
./vendor/bin/pint
Pint found and fixed some issues in three files:
If we take a closer look at GitHub commit, these are the changes.
I just used this Model earlier, changed the code, and forgot to remove the Model from the use
section.
There's no point in having @return array
if we use the (): array
in the function name. Remember, I've pasted this code example from the Sluggable package Readme.
This may look like a personal preference, but over the years, I found it a good practice: just more convenient to add more array items in the future if there's already a comma present.
And again, this code came by pasting from the package Readme file.
According to standards, imports in the use
section should be alphabetically ordered. So Pint suggested precisely that.
And that's it from Laravel Pint. It didn't spot any more flaws or styling issues in our code, which means our code styling is pretty good!
Generally, Pint uses only one of the possible code styling "rules preset" called "laravel". If you don't like its suggestions, you can customize it to use a well-known PSR-12 standard, create your own preset, or override/turn off specific rules. It's all described in the Pint documentation.
Now, remember: all those code styling rules are optional and opinionated. There are standards like PSR, but they are not "sacred", and if you don't style your code precisely as they advise, it's not a big deal. The problem appears when working in a team, and you write code differently, so those minor fixes here and there make it hard to read and review the teammate's code.
You can also read this tutorial: Code Styling in Laravel: 11 Common Mistakes
If Laravel Pint above takes care of how the code looks (styling), then Larastan is about how the code works (structure).
Here's the official description of the tool:
Larastan is a PHPStan wrapper for Laravel. Larastan focuses on finding errors in your code. It catches whole classes of bugs even before you write tests for the code.
Here's what we need to do to run this analysis.
Obviously, install Larastan.
composer require nunomaduro/larastan --dev
Then we need to create a configuration file called phpstan.neon
in the main folder of our Laravel application.
There are many levels and options available, but for now, we will stick to the default recommendation from the official docs:
phpstan.neon:
includes: - ./vendor/nunomaduro/larastan/extension.neon parameters: paths: - app/ # Level 9 is the highest level level: 5
And that's it, we can execute this in Terminal:
./vendor/bin/phpstan analyse
This is the result:
Ok, so we have errors! But don't be afraid: these are only potential errors, as Larastan/PHPStan is trying to look for mismatches in the variable names/definition, which may lead to some bugs.
For example, in this case, all those 11 errors happen because Larastan "doesn't like" Laravel "magic" of API Resources where we call $this->id
without really defining what $this
really is. It also conveniently provides the URL where you can read more about the flagged error.
There are a few things that we may choose to do here.
Ok, if Larastan doesn't "understand" what $this->id
is, let's explain it.
There are actually various ways you can do it, by providing comments before the method and/or class name, but after some experiments, I landed on this solution. See @mixin
and @property
above the Class definition:
app/Http/Resources/TravelResource.php:
/*** @mixin \App\Models\Travel* @property int $number_of_nights*/class TravelResource extends JsonResource{ /** * Transform the resource into an array. * * @return array<string, mixed> */ public function toArray(Request $request): array { return [ 'id' => $this->id, 'name' => $this->name, 'slug' => $this->slug, 'description' => $this->description, 'number_of_days' => $this->number_of_days, 'number_of_nights' => $this->number_of_nights, ]; }}
With the @mixin
, we tell Larastan that there will be that Travel
Class used inside this JsonResource
Class. This way, Larastan "understands" all the $this->id
and $this->slug
except one. See below.
For property number_of_nights
, we need to define a special @property
because that is a "virtual" column, the Accessor, remember? So it isn't actually defined in the Travel
Model.
Re-run Larastan and we have errors only in another JsonResource
!
So, let's perform the same change there.
app/Http/Resources/TourResource.php:
/*** @mixin \App\Models\Tour*/class TourResource extends JsonResource{ /** * Transform the resource into an array. * * @return array<string, mixed> */ public function toArray(Request $request): array { return [ 'id' => $this->id, 'name' => $this->name, 'starting_date' => $this->starting_date, 'ending_date' => $this->ending_date, 'price' => number_format($this->price, 2), ]; }}
And... Larastan is showing that we're ok now!
You could "disagree" with Larastan and tell it to accept Laravel "magic" and not check specific rules in some files.
For that, we add a line in the phpstan.neon
:
phpstan.neon:
parameters: paths: - app/ # Level 9 is the highest level level: 5 ignoreErrors: - '#Access to an undefined property App\\Http\\Resources\\[a-zA-Z0-9::a-zA-Z]#'
And then Larastan won't flag those errors, even if you don't add those @mixin
and @property
comments in the API Resource files.