Courses

Larastan: Catch Bugs with Static Analysis

Example 1: Basic Checks

As with many things, we will learn better by looking at real-life examples. Let's look at some of the most common issues you'll encounter and how to fix them.

For each example, we'll tell you on what level we saw the error and what we did to fix it. As a bonus, we'll include what the fix will bring to your code!


So, you just installed Larastan and attempted to do a first run on level 1 as it is the lowest level. Here's what you might see:

------ ---------------------------------------------------------
Line Http/Controllers/Admin/UsersController.php
------ ---------------------------------------------------------
21 Relation 'roles' is not found in App\Models\User model.
------ ---------------------------------------------------------
------ ---------------------------------------------------------
Line Http/Controllers/Admin/HomeController.php
------ ---------------------------------------------------------
15 Call to an undefined method App\Http\Controllers\Admin\HomeController::getUsers().
------ ---------------------------------------------------------

These are basic errors that you might find in your app especially if you didn't use types previously or have a typo somewhere you didn't notice yet.

Our used configuration

phpstan.neon

includes:
- ./vendor/nunomaduro/larastan/extension.neon
 
parameters:
paths:
- app/
# Level 9 is the highest level
level: 1

Let's run the analysis:

./vendor/bin/phpstan analyse

Unknown Relation on Model

You should see something like this:

------ ---------------------------------------------------------
Line Http/Controllers/Admin/UsersController.php
------ ---------------------------------------------------------
21 Relation 'roles' is not found in App\Models\User model.
------ ---------------------------------------------------------

Hmm, why did this happen? We already have a relationship there:

app/Models/User.php

public function roles()
{
return $this->belongsToMany(Role::class);
}

So why is this showing us an error on level 1? Well, it checks for unknown methods in our classes. And in this case, our Model User has a relationship, but we don't know what exactly it returns. Let's add a return type and see if that fixes it:

app/Models/User.php

use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
// ...
 
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class);
}

Running ./vendor/bin/phpstan analyse again should now return:

[OK] No errors

Why did this happen? Well - we've just told our code that this method returns a BelongsToMany relationship. This allows Larastan to know what methods are available in this relationship.

Typo in Code

We are all humans and we make mistakes. Let's add a typo to our code and see what happens:

app/Http/Controllers/Admin/HomeController.php

use App\Models\User;
 
class HomeController
{
public function index()
{
return view('home')
->with('totalUsers', $this->getUsers());
}
 
protected function getUser()
{
return User::count();
}
}

Running ./vendor/bin/phpstan analyse again should now return:

------ ---------------------------------------------------------
Line Http/Controllers/Admin/HomeController.php
------ ---------------------------------------------------------
15 Call to an undefined method App\Http\Controllers\Admin\HomeController::getUsers().
------ ---------------------------------------------------------

While our typo right now was intentional - we can quickly see a benefit of this. It did not allow us to pass the checks without double-checking the function name and making sure it was correct.

No comments or questions yet...