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.
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:
$account = $this->account();
// use it as before...
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: