How to use session in Symfony

前端 未结 2 1280
再見小時候
再見小時候 2021-01-23 09:11

I\'m getting a hard time trying to understand how symfony session works.
And couldn\'t find the answer I\'m looking for here on S.O. or other external sources.

[SETT

相关标签:
2条回答
  • 2021-01-23 09:49

    One way of getting Sessions from controller is:

    $session = $this->get("session");

    Setter: $session->set('id','<value>');

    Getter: $session->get('id');

    Full Code

    public function sessionAction(Request $request) {
        $em = $this->getDoctrine()->getManager();
        $site = $em->getRepository('SiteBundle:Site')->findOneBy(array('url'=>$request->getSchemeAndHttpHost()));
        if($site) {
            $session = $this->get("session");
            $session->set('id',$site->getId());
            $session->set('url',$site->getUrl());
            $session->set('name',$site->getName());
        } else {
            [...]
        }
    }
    

    Update-1:

    Create service to set session variables

    AppBundle\EventListener\SessionHandler.php

    <?php
    
    namespace AppBundle\EventListener;
    
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Routing\Router;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    
    class SessionHandler {
    
        private $doctrine;
        private $container;
        private $router;
    
        public function __construct($doctrine, $router, $container) {
            $this->doctrine  = $doctrine;
            $this->router    = $router;
            $this->container = $container;
        }
    
        public function setSession() {
            $route = $this->container->get('request')->get('_route');
            $site = $this->doctrine->getRepository('SiteBundle:Site')->findOneBy(array('url' => $route->getUri()));
            if($site) {
                $session = $this->container->get("session");
                $session->set('id',$site->getId());
                $session->set('url',$site->getUrl());
                $session->set('name',$site->getName());
            } else {
                [...]
            }
        }
    }
    

    AppBundle\Resources\config\services.yml

    Option-1

    Call setSession() function on each page load event.

    session_handler:
            class: AppBundle\EventListener\SessionHandler
            arguments: [@doctrine, @router, @service_container]
            tags:
                - {name: kernel.event_listener, event: kernel.request, method: setSession} 
    

    Option-2

    Call setSession() function manually where you need to set session.

    session_handler:
            class: AppBundle\EventListener\SessionHandler
            arguments: [@doctrine, @router, @service_container]
            tags:
                - {name: kernel.event_listener }
    

    Call setSession() function from controller

    $sessionService = $this->get('session_handler');
    $sessionService->setSession();
    
    0 讨论(0)
  • 2021-01-23 10:11

    Well, first a big thanks to Gopal Joshi who helped me figure out a lot of things... :)

    For those who come later, read his answer, it's helpful in a lot of ways...
    I would also suggest reading this question, it goes in pair with the current question.

    Meanwhile, I came out with this:

    1: Register the service

    AppBundle\Resources\config\services.yml

    app.session_handler:
        class: SalonBundle\Services\SessionHandler
        arguments:
            - "@doctrine"
            - "@router"
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: setSession }
    

    First, I will point that I use the argument @router, but unless you need to redirect the response to another url, it's not needed.

    2: Create the service

    AppBundle\EventListener\SessionHandler.php

    <?php
    
    namespace AppBundle\EventListener;
    
    use Doctrine\Bundle\DoctrineBundle\Registry;
    use Symfony\Bundle\FrameworkBundle\Routing\Router;
    use Symfony\Component\HttpFoundation\RedirectResponse;
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    
    class SessionHandler {
    
        private $doctrine;
        private $router;
    
        public function __construct(Registry $doctrine, Router $router) {
            //Make sure to type $doctrine and $router in the constructor.
            //Else some methods can't be found directly, and Symfony have to do the job for you
            //I guess it would make a big project a bit slower without the types
            $this->doctrine=$doctrine;
            $this->router=$router;
        }
    
        public function setSession(GetResponseEvent $responseEvent) {
            //This function parameter call on GetResponseEvent class
            //for the same reason as above.
            $site=$this->doctrine->getRepository('AppBundle:Site')->findOneBy(array('url'=>$responseEvent->getRequest()->getSchemeAndHttpHost()));
            if($site) {
                $session=$responseEvent->getRequest()->getSession();
                $session->clear();
                $session->set('site', $site);
            } else {
                if($responseEvent->getRequest()->get('_route') != 'some_route') {
                    //This next line is the only reason as to why we pass "@router" as argument
                    $responseEvent->setResponse(new RedirectResponse($this->router->generate('some_route')));
                }
            }
        }
    }
    

    To sum things up, it's very close to Gopal Joshi answer...
    In fact, it's the same, just with some code cleanup...
    Both his answer and mine are working...
    The only difference is that mine won't show warning like:
    Method 'methodName()' not found or import 'import\path\and\name' is never used

    Gopal Joshi, if you happen to read my answer, I'm asking you, which one should I validate?
    Being honest here, most of the credits is yours, so I will validate the answer you want... ;)

    0 讨论(0)
提交回复
热议问题