eComEvo
eComEvo

Reputation: 12549

Laravel session data not sticking across page loads

I tried running the following code:

Session::put('progress', '5%');

dd(Session::get('progress'));

This will show '5%' in the dump.

If I rerun the same page but comment out Session::put('progress', '5%'); so that only the dd() line is called, I get a null value instead of the 5% values stored in the previous page load.

Here is my sessions config, so I know it should be storing the data:

'driver' => 'native',
'lifetime' => 120,
'expire_on_close' => false,

Why is Laravel not storing the session data across page loads?

Upvotes: 31

Views: 39229

Answers (6)

T5k
T5k

Reputation: 51

Often, my app would store the session variables, but sometimes (~5% of the time) it would not. I tried multiple approaches, however, this is the only one that has been working reliably (so far):

$request->session()->put('key', 'value');
$request->session()->save();
$request->session()->regenerate();

Cheers :)

Upvotes: 1

Alex Pilyavskiy
Alex Pilyavskiy

Reputation: 140

I moved the session middleware

\Illuminate\Session\Middleware\StartSession::class

to the property $middleware in

app/Http/Kernel.php

In this case, you need to remove it from the web group ($middlewareGroups)

enter image description here

It helped me, I hope it helps you too

Upvotes: 1

Rubens Mariuzzo
Rubens Mariuzzo

Reputation: 29241

The problem is because you are killing the script before Laravel finishes its application lifecycle, so the values put in session (but not yet stored) got killed too.

When a Laravel application lifecycle starts, any value put in Session are not yet stored until the application lifecycle ends. That is when any value put in Session will be finally/really stored.

If you check the source you will find the same aforementioned behavior:

 public function put($key, $value)
 {
     $all = $this->all();

     array_set($all, $key, $value);

     $this->replace($all);
 }

If you want to test it, do the following:

  1. Store a value in session without killing the script.

    Route::get('test', function() {
        Session::put('progress', '5%');
        // dd(Session::get('progress'));
    });
    
  2. Retrieve the value already stored:

    Route::get('test', function() {
        // Session::put('progress', '5%');
        dd(Session::get('progress'));
    });
    

Upvotes: 68

sergei
sergei

Reputation: 823

Rubens Mariuzzo's answer is very good. I just want to add that if you need the data to be stored immediately you could use the save method:

Session::put('progress', '5%');
Session::save();

Upvotes: 49

Artur Owczarek
Artur Owczarek

Reputation: 1167

In my case I flashed the variable in one request and then put it into session in another request (with the same name).

Unfortunatelly, terminating method went through all the previously flashed properties and cleaned my newly created session property (it was flushed in previous request so laravel thought it was no longer required and couldn't tell it was newly created). I figured it out debugging Kernel->terminateMiddleware method. You can put a breakpoint in terminating method. At some stage it reaches Store->ageFlashData. This is the method responsible for deleting my property.

Upvotes: 0

Alex
Alex

Reputation: 81

For me, even after data has been stored to session properly:

    dd(Session::all());

returns nothing, but:

    print_r(Session::all());

returns all session data!

Upvotes: 0

Related Questions