Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

saadbm's avatar

Best solution for different code/algorithms for different user roles

Hello, I tend to use https://github.com/Zizaco/entrust for role based authentication system. And I end up having chain if-else statements like this in my Controllers and/or Classes:

if($user->hasRole('admin')){
    //do something admin would do
}
else if($user->hasRole('customer')){
    //do something customer will do
}
else if($user->hasRole('manager')){
    //do something manager will do
}
.....

I have the feeling this is a horrible coding practice. Can anyone suggest a better solution/design pattern to implementing these role checks and executing different code/algorithms based on User's roles.

0 likes
1 reply
andonovn's avatar
andonovn
Best Answer
Level 22

@saadbm Normally, you would have different endpoints for different roles. And you can protect these endpoints as simple as abort_unless($user->hasRole('manager'). That way, you are sure that the code below will be executed only for users with role of manager. Example:

routes/web.php

Route::post('admin/users', 'Admin/UsersController@create');
Route::post('users', 'UsersController@create');

app/Http/Controllers/Admin/UsersController

public function create(Request $request)
{
    abort_unless($request->user()->hasRole('admin');
    //do something admin would do
}

If you can't have different endpoints, then surely the executed code will have something in common. So you can define an interface and create a factory that will return an implementation of that interface based on the user's role. So the only place you will have these if-else statements would be inside the factory. And let's say that "something in common" is an algorithm to calculate the experience based on the user's role, so I can post a practical example:

ExperienceCalculatorFactory.php

public function makeFor(User $user) : ExperienceCalculatorContract
{
    if ($user->hasRole('admin')) {
        return app(AdminExperienceCalculator::class);
    }
    if ($user->hasRole('customer')) {
        return app(CustomerExperienceCalculator::class);
    }
    if ($user->hasRole('manager')){
        return app(ManagerExperienceCalculator::class);
    }
    // other possible roles here
    throw new UndefinedExperienceCalculatorException;
}

ExperienceCalculatorContract.php

interface ExperienceCalculatorContract {
    public function calculate() : void;
}

AdminExperienceCalculator.php

class AdminExperienceCalculator implements ExperienceCalculatorContract {
    public function calculate() : void
    {
        //do something admin would do
    }
}

CustomerExperienceCalculator.php

class CustomerExperienceCalculator implements ExperienceCalculatorContract {
    public function calculate() : void
    {
        //do something customer would do
    }
}

ManagerExperienceCalculator.php

class ManagerExperienceCalculator implements ExperienceCalculatorContract {
    public function calculate() : void
    {
        //do something manager would do
    }
}

And the usage (ie in your controllers) would be as simple as:

app(ExperienceCalculatorFactory::class)
    ->makeFor($user)
    ->calculate();
1 like

Please or to participate in this conversation.