不建议再使用 Request::getSession()

Contributed by
Florent Mata
in #26564.

在没有 session 存在的情况下使用 Request::getSession() 已经被 Symfony 4.1 降格,而且在 Symfony 5.0 中将抛出异常。解决方案是始终使用 Request::hasSession() 方法检查 session 是否存在:

1
2
3
4
// ...
if ($request->hasSession() && ($session = $request->getSession())) {
    $session->set('some_key', 'some_value');
}

允许对使用了session的请求进行缓存

Contributed by
Yanick Witschi
in #26681.

任何时候 session 都始于一个请求,Symfony 将响应转成了一个私有的、不可缓存的响应,以防止泄露隐私。但是,就算请求利用了 session,在某些条件下也是可以被缓存的。

例如,关于某些用户群组的信息,可以对所有“属于该群组”的用户进行缓存。处理这些高级缓存场景已经超出 Symfony 的职责范围,但它们可以通过 FOSHttpCacheBundle 来加以解决。

为了关闭默认的 “Symfony让使用了session的请求不可缓存”这一行为, 在 Symfony 4.1 中我们添加了 NO_AUTO_CACHE_CONTROL_HEADER 头,你可以把它加到响应中去:

1
2
3
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
 
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');

允许session迁移

Contributed by
Ross Motley
in #26096.

迁移 sessions (比如,从filesystem 转向 database) 是一个讲究技巧的操作,通常要终结所有即存的 session。这就是为什么在 Symfony 4.1 中我们引入了全新的 MigratingSessionHandler 类,来让新旧 session handler 的转移不必再丢失 session 数据。

推荐三步法来完成迁移:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
// migrating 类的构造器是: MigratingSessionHandler($currentHandler, $writeOnlyHandler)
// Step 1. 在 "garbage collection 时段" 将全部 session 收集到新的 storage 中,此时进行这一步
$sessionStorage = new MigratingSessionHandler($oldSessionStorage, $newSessionStorage);
 
// Step 2. Do this while you verify that the new storage handler works as expected
// Step 2. 新的 storage handler 如预期般运行时,进行这一步
$sessionStorage = new MigratingSessionHandler($newSessionStorage, $oldSessionStorage);
 
// Step 3. Your app is now ready to switch to the new storage handler
// Step 3. 现在你的程序已经准备好切换到新的 storage handler 了
$sessionStorage = $newSessionStorage;