Someone recently asked me for help to debug why a session value wasn't being set as expected.
They had a controller action which was setting a session value if empty, and then returning that value. But when they added some debug statements, they found that the value was always empty, even if they refreshed the page multiple times.
The expectation was that it should be empty the first time, but then be present on additional calls.
Here's a simplified version of what they were trying:
// inside the controller action and greatly simplified to show in one block
if (session()->has('some-key')) {
dump('key exists');
$value = session('some-key');
} else {
dump('key does not exist');
session(['some-key' => 'some-value']);
$value = session('some-key');
}
dd($value);
Every time they refreshed the page, it would output key does not exist
and some-value
. Based on this, they knew the session value wasn't being persisted, but why?
Here's where it helps to know how Laravel sessions work. They don't use the underlying PHP session mechanism, but are instead implemented via the Laravel SessionManager
and the StartSession
middleware.
Let's peek at the relevant method in that middleware (I stripped out all comments, except my one comment, to keep it simple)
protected function handleStatefulRequest(Request $request, $session, Closure $next)
{
$request->setLaravelSession(
$this->startSession($request, $session)
);
$this->collectGarbage($session);
$response = $next($request); // <--- This is where your controller action runs
$this->storeCurrentUrl($request, $session);
$this->addCookieToResponse($response, $session);
$this->saveSession($request);
return $response;
}
Note that the saveSession
method isn't called until the response side of the middleware, which runs after the controller action.
So by putting a dd()
inside our controller action, we kill the PHP request before this middleware can finish its job. If he had used dump
instead of dd
, it would have worked as expected.
Mystery solved!
Here to help,
Joel
P.S. dd
is useful at times, but Xdebug is an even better debugging tool. If you need help getting Xdebug running in your project, let me know.