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

1

7

I'm a little confused as to the "right" way to retrieve the current session object within a controller in Symfony 5.3. The current documentation says to typehint an argument as SessionInterface. However, this Symfony blog post says SessionInterface has been deprecated in favor of using RequestStack.

In services it's clear that I should inject RequestStack and call $requestStack->getSession(). However, in most controller methods I'm already injecting the Request object which also has a getSession() method that seems to work.

Is it okay to get the session from the Request object, or should I inject RequestStack in addition to Request in my controller methods (this feels like duplication almost)


A quick code example:

// 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 
}
Hamrah answered 24/6, 2021 at 5:33 Comment(0)
H
9

The documentation has not yet been updated.*

In Symfony 5.3+, outside of controller context, you should get the session from the RequestStack, as you are doing and it's described on the blog. There it says the reasons why getting the session data from the Request object feels wrong, and why the SessionInterface is being deprecated in favour of the 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.

If you are already getting the Request object (e.g. you are on a controller context), you can get it from there directly as well, as Request::getSession() has not been deprecated. That's fine, and it's simply part of the convenience of working within the framework.

But if you are not, get the RequestStack instead of the SessionInterface directly.

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

(And if you do this, you could get the Request object from there as well, swapping the injection of a data object with a service-like object to get that data).

* Remember that the docs themselves are open-source, and they welcome pull-requests to keep them updated!

Hypogene answered 24/6, 2021 at 6:1 Comment(1)
I found the blog (specifically what you quoted) more confusing. It says it feels odd to handle sessions as part of the HttpFoundation component, yet the RequestStack is part of that component. Looking into the RequestStack::getSession() source code, all it's really doing is calling Request::getSession() anyway, so it feels like a wrapper/convenience method to me more than anything else. The docs definitely need some updating, I'll look into opening a PR for this. Thanks for the reply.Hamrah

© 2022 - 2024 — McMap. All rights reserved.