如何在 Symfony 5.3 的控制器中获取 Session 对象?

How should one get Session object in a controller on Symfony 5.3?

对于在 Symfony 5.3 的控制器中检索当前会话对象的“正确”方法,我有点困惑。 current documentation says to typehint an argument as SessionInterface. However, this Symfony blog post 表示 SessionInterface 已被弃用,转而使用 RequestStack

在服务中,很明显我应该注入 RequestStack 并调用 $requestStack->getSession()。然而,在大多数控制器方法中,我已经注入了 Request 对象,它也有一个似乎有效的 getSession() 方法。

是否可以从 Request 对象获取会话,或者我应该在我的控制器方法 Request 之外注入 RequestStack (这感觉几乎是重复)


快速代码示例:

// in a controller
public function myRoute(Request $request): Response
{
    $session = $request->getSession(); // this works
}

// seems silly to also inject RequestStack when I already have Request
public function myRoute(Request $request, RequestStack $requestStack): Response
{
    $reqestStack->getSession(); // this works
}

// the way current documentation shows
public function myRoute(Request $request, SessionInterface $session): Response
{
    // this causes a deprecation warning from injecting SessionInterface 
}

文档尚未更新。*

在 Symfony 5.3+ 中,在控制器上下文之外,您应该从 RequestStack 获取会话,就像您正在做的那样,它在博客上有描述。那里说了为什么从 Request 对象获取会话数据感觉不对,以及为什么 SessionInterface 被弃用而赞成 RequestStack:

  • Session is a data object (e.g. like the Request object) so there shouldn’t be a service defined for it in the container;
  • Sessions are not part of the HTTP specification (either HTTP/1.1, HTTP/2 or HTTP/3) because HTTP is stateless. That’s why it feels odd to handle sessions as part of the HttpFoundation component.

如果您已经获取Request对象(例如,您在控制器上下文中),您也可以直接从那里获取它,因为Request::getSession() 尚未弃用。这很好,这只是在框架内工作的便利的一部分。

但如果不是,请直接获取 RequestStack 而不是 SessionInterface

public function myRoute(RequestStack $requestStack): Response
{
    $requestStack->getSession();
}

(如果你这样做,你也可以从那里获得 Request 对象,将数据对象的注入与类似服务的对象交换以获得该数据)。

* 请记住,文档本身是开源的,他们欢迎拉取请求以保持更新!