There are many reasons people want session data in the controller's constructor. Let's look at 2 examples:
Sharing the current user to all views:
Instead of using auth()->user() in your views, it's sometimes nicer to just have a global $user variable available across all views. A quick way to achieve that is to add a constructor to the base controller and share it from there:
In both of these cases, the code in the constructor assumes that the session is primed and ready. But if we try to run the code, it'll fail. At this point, the request has not yet been routed and no session data is available.
For every request, Laravel will fire the Authenticated event when the user is authenticated. You can listen for this event in a service provider, and share the $user from there:
Let's go back to the second example in the problem section. Instead of finding the current account directly in the constructor, you can put its logic into its own method and only call it when you actually need it:
publicfunctionindex(){
$account = $this->account();
// use it as before...
}
protectedfunctionaccount(){
return Account::find(session('account_id'));
}
This is great for new projects, but can be a little tedious if you already have a big project that relies on the property being available across all controller methods. For such cases, you can use an inline middleware.
Inline middleware are a little more involved than the other solutions, but are probably the most flexible.
You may have seen $this->middleware('auth') before, which registers an existing middleware directly from within the controller constructor. What you may not know is that you can actually use a closure to define the middleware on the fly.
Using an inline middleware, we can hook into the request's routing, so that we have full access to the session:
As you can see, this is a little more complex than the other solutions, but it gives us the most flexibilty.
These 4 solutions should cover all your session needs. If there's any controller session problem that's not solved by these, or if you have any better solutions, do let me know!
Questions? Comments? Complaints?
Ping me on Twitter.
Let's take a look at a neat little feature coming in PHP 7.1: easily converting any callable into a proper Closure using the new Closure::fromCallable() method.