The session hasn't started yet, so it is not available within a ServiceProvider - the official line has been to create a Middleware in these circumstances.
Retrieving session data in class instantiated with a Service Provider
Hello,
I'm trying to set and retrieve Session data in a class that is instantiated with a Service Provider. Setting the data works fine, but after refreshing the page the data is gone. I know it has something to do with the order of bootstrapping the Framework but I can't figure out how to make it work.
Here's my Service Provider:
namespace App\Providers;
use App\Illuminate\Profile\Profile;
use App\Illuminate\Contracts\Profile\Registrar;
use Illuminate\Support\ServiceProvider;
class ProfileServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
$this->app->bind('App\Illuminate\Contracts\Profile\Registrar', 'App\Illuminate\Profile\Profile');
}
}
And here's the 'App\Illuminate\Profile\Profile' class:
namespace App\Illuminate\Profile;
use App\Models\Profiles;
use Illuminate\Http\Request;
use App\Illuminate\Contracts\Profile\Registrar;
class Profile implements Registrar
{
/**
* The current profile
*
* @var object
**/
protected $profile;
function __construct(Request $request)
{
$this->request = $request;
$this->setProfile($this->getHost());
}
/**
* Returns the profile or an object value
*
* @param string
* @return mixed: null or a string which corresponds to a database column
**/
public function get($value = null)
{
return is_null($value) ? $this->profile : $this->profile->$value;
}
/**
* Sets the current profile (override)
*
* @param string
**/
public function setProfile($host)
{
if( $this->request->session()->has('profile_override') )
{
$host = $this->request->session()->get('profile_override');
}
$this->profile = Profiles::where('host', $host)->firstOrFail();
}
function switchProfile($host)
{
$this->setProfile($host);
$this->request->session()->put('profile_override', $this->profile->host);
}
/**
* Returns the http host
*
* @return string
**/
protected function getHost()
{
if( env('APP_ENV') == 'local' )
{
return env('PROFILE_LOCAL');
}
return implode('.', array_slice(explode('.', $this->request->server('HTTP_HOST')), -2));
}
}
I'd like to switch profile using the switchProfile() method from anywhere in my application. At that point, the Session data is updated with the correct key and value. But when I refresh the page it seems to be gone. Can someone please explain why?
Another question, unrelated to the problem above. Why can't I typehint the Request class on a controller method? It only works in the constructor. When typehinting in a method I get the following error: Argument 2 passed to App\Illuminate\Profile\Profile::setProfile() must be an instance of Illuminate\Http\Request, none given.
Any help would be appreciated!
True, the 'web' Middleware group is run after all the Service Providers are booted. So Session isn't available yet. This is now set as default by the way: https://github.com/laravel/laravel/commit/5c30c98db96459b4cc878d085490e4677b0b67ed
I added a Middleware to set the profile. That works fine, thanks for suggesting that!
Another problem turned out to be complete something else. I was using a controller to test the functionality within the Profile class. In there I had two methods which each would dd() some data.
As I said, the Session data was set, but it wouldn't persist in additional requests. Turns out the problem was dumping the data instead of letting the method render properly. Once I added a view at the end and let everything run the Session data WOULD persist. Reference here: http://stackoverflow.com/a/31809419 (answer from spedley).
Funny how you can fool yourself sometimes... Like adding CSS and refreshing the live website. I guess we've all been there :)
Please or to participate in this conversation.