Deprecate some uses of Request::getSession()
Using Request::getSession()
when no session exists has been deprecated in
Symfony 4.1 and it will throw an exception in Symfony 5.0. The solution is to
always check first if a session exists with the Request::hasSession()
method:
1 2 3 4
// ...
if ($request->hasSession() && ($session = $request->getSession())) {
$session->set('some_key', 'some_value');
}
Allow to cache requests that use sessions
Whenever the session is started during a request, Symfony turns the response into a private non-cacheable response to prevent leaking private information. However, even requests making use of the session can be cached under some circumstances.
For example, information related to some user group could be cached for all the users belonging to that group. Handling these advanced caching scenarios is out of the scope of Symfony, but they can be solved with the FOSHttpCacheBundle.
In order to disable the default Symfony behavior that makes requests using the
session uncacheable, in Symfony 4.1 we added the NO_AUTO_CACHE_CONTROL_HEADER
header that you can add to responses:
1 2 3
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
Allow to migrate sessions
Migrating sessions (e.g. from the filesystem to the database) is a tricky
operation that usually ends up losing all the existing sessions. That's why in
Symfony 4.1 we've introduced a new MigratingSessionHandler
class to allow
migrate between old and new save handlers without losing session data.
It's recommended to do the migration in three steps:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MigratingSessionHandler;
$oldSessionStorage = ...;
$newSessionStorage = ...;
// The constructor of the migrating class are: MigratingSessionHandler($currentHandler, $writeOnlyHandler)
// Step 1. Do this during the "garbage collection period of time" to get all sessions in the new storage
$sessionStorage = new MigratingSessionHandler($oldSessionStorage, $newSessionStorage);
// Step 2. Do this while you verify that the new storage handler works as expected
$sessionStorage = new MigratingSessionHandler($newSessionStorage, $oldSessionStorage);
// Step 3. Your app is now ready to switch to the new storage handler
$sessionStorage = $newSessionStorage;
Nice, especially the migration will be sweet to have!
Nice, session migration is a cool feature. There is a little typo in the first code snippet: missing parenthesis in $request->getSession.
The DX on this is very confusing, at least the example given makes no sense whatsoever.
@Luis it's really hard to show a full real example. The three steps must be done separately. You switch from one to the next step after each period is completed: "garbage collection", "verification", etc.
Is session migration intended to be a one time thing (such as during a post deployment command)? For example, moving sessions from filesystem to redis only needs to happen once if the application now primarily uses redis?
@David, no - it's a 3 step migration, you basically create your new session handler and this migration session handler, change your current one with the migration one. Leave it in production for the TTL of your current time (to ensure that all sessions have been migrated) then you can remove the old and the migration and change on settings to use the new one. The advantage of doing this way is that it will work with everything that can handle sessions and you are in control of it (deploy-free, error-free). If anything happens you still have the old, you just have to rollback for instance.