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

LaraBABA's avatar

How to echo single json object after a query

Hi,

Quick question please.

I have a query like this one in my user model

   public function getRole(){

  $role = DB::table('users')
            ->join('roles', 'users.role_id', '=', 'roles.id')
            ->select('roles.name')
            ->get();


   return $role;
   }

When I return it to my home Controller public function index(Request $request) {

  $loggedInRole = $request->user()->getRole();
  echo $loggedInRole;
  die;

  }

I get this which seems to be in json [{"name":"manager"}]

Is there a shortcut on the query side where I can simply output "manager" on its own without objects?

I tried ->first(), same problem. I am looking in the doc but just cannot find what I am looking for.

Thank you.

0 likes
10 replies
tykus's avatar

Your getRole() method is not returning a single Role instance; it returns a Collection of stdClass instances; these are unrelated to the authenticated user; it will return the role for every user. It seems that this is not what you intend.

If you can use Eloquent relations instead of a query, then you can get the authenticated user's role (assuming your have a role_id on the users table) using a belongsTo relationship:

public function role()
{
    return $this->belongsTo(Role::class);
}

If you wanted, you could then add a getter to your User model to get the role name only:

public function getRole()
{
    return optional($this->role)->name;
}

The optional helper will return null rather than throwing a Trying to get property of non-object error when there is no role associated with the user.

1 like
LaraBABA's avatar

My apology, this is what I wanted to do first:

  $user_id = Auth::user()->id;
  $role = DB::table('users')
            ->join('roles', 'users.role_id', '=', 'roles.id')
            ->select('roles.name')
            ->where('users.id', $user_id)
            ->first();


   return $role;

Yes your solution works like a charm.

I hope I am doing this right, I am trying to block certain routes/views when users are not allowed.

For example in my HomeController I had added this:

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */

       public function index(Request $request)
      {

      $loggedInRole = $request->user()->getRole();
      $allow = ['admin', 'manager'];

      if(in_array($loggedInRole, $allow)){
      return view('home');

       }

      }
}

I am not yet confident if this is the best approach as I have a dillemma, do I need to block the views or the routes directly in the web.php?

What would you suggest, please? Add this code in the controllers or in the web.php only?

I do find Laravel tough to learn (my first framework), really trying hard daily but I think it is going to take me some time to understand everything:-)

tykus's avatar

This could be extracted to a middleware, which would keep your Controller methods clean and makes the protection of certain route much more flexible (you could specify any role(s) for a given route. e.g. https://laravel.com/docs/5.5/middleware#middleware-parameters

Your steps to create this are:

Create the new middleware - which will be generated in app/Http/Middleware when you use the following artisan command:

php artisan make:middleware CheckRole

Inside the middleware's handle method, add the following logic to check the authenticated users role:

    public function handle($request, Closure $next, ...$roles)
    {
        if (! in_array($request->user()->getRole(), $roles)) {
            return back(); // or redirect somewhere else
        }

        return $next($request);
    }

Apply the middleware to the appropriate routes:

Route::get('/', 'HomeController@index')->middleware('role:admin,manager');
1 like
Cronix's avatar

Can't you just return $role->name instead of returning the $role object?

1 like
LaraBABA's avatar

@tykusThank you for the reply, this is superb and will really help!

I had to add 'role' => \App\Http\Middleware\CheckRole::class, in the routemiddleware as I was getting a class not found error.

So if I understand correctly, the middleware('role:admin,manager'); in the route will create an array called "$role". From there, this array will be passed to the request as the third parameter as: public function handle($request, Closure $next, $role)

I expected it to work this way but strangely enough, there is nothing in the $role(null) after adding the Route causing the error: in_array() expects parameter 2 to be array, string given

Any idea why please?

tykus's avatar

Sorry, I forgot to show you how to register the route middleware.

public function handle($request, Closure $next, ...$roles)

The spread operator (...) will take all the roles (admin, manager in this case) and place them in an array.

1 like
LaraBABA's avatar

Thanks Tykus, Yes this is what I spoke about in my reply just above but I must have something missing as I am not getting any data in my array on request.

tykus's avatar
tykus
Best Answer
Level 104

Just for clarity, the role:admin,manager syntax will invoke the role middleware and pass to it's handle method the arguments after the : symbol. These could be separate arguments, but in our case we want an array, so the spread operator gathers all arguments into a single array.

The spread operator is a PHP 5.6 feature, but I expect you are already on min. 5.6?

1 like
LaraBABA's avatar

Thanks Tykus, I am using PHP 7.1.7.

ahahaha, got it now. I have actually never used a spread operator before in procedural programming.

When you added "..." I thought you meant "Put your variables there..."

I just watched a Youtube video about it, now I understand what you mean.

Quick question for you, why does the CSRF kicks in when the middleware starts a request in laravel 5.5 please

Call to a member function setCookie() on null

 protected function addCookieToResponse($request, $response)
    {
        $config = config('session');
 
        $response->headers->setCookie(
            new Cookie(
                'XSRF-TOKEN', $request->session()->token(), $this->availableAt(60 * $config['lifetime']),
                $config['path'], $config['domain'], $config['secure'], false, false, $config['same_site'] ?? null
            )
        );
 
        return $response;
    }
}
LaraBABA's avatar

Ok Go it, just changed the return to a response in the middleware

return response()->view('not-found');

Instead of this: return back();

Thanks again!!! You are a good man!

Please or to participate in this conversation.