如何在Symfony中使用会话

时间:2016-11-21 02:10:52

标签: symfony

我很难理解symfony会话是如何运作的 并且找不到我在S.O.上寻找的答案。或其他外部来源。

[设置]

  • Symfony 3
  • SiteEntity(保存网站信息,例如网站网址,网站名称等)
  • 网站结构由页面周围的布局(layout.html.twig)
  • 组成

[问题]

相当容易理解,我无法弄清楚从哪里开始我的会话。 我现在所做的是在SiteController

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

如何在网站加载时调用此功能来创建会话?

此外,这是正确的方法吗?

2 个答案:

答案 0 :(得分:2)

嗯,首先非常感谢Gopal Joshi帮助我找出很多东西... :)

对于那些后来来的人,请阅读他的回答,这在很多方面都很有用...... 我还建议阅读此question,它与当前问题配对。

与此同时,我出来了:

1:注册服务

<强> 的appbundle \资源\配置\ services.yml

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

首先,我将指出我使用参数@router,但除非您需要将响应重定向到另一个网址,否则不需要。

2:创建服务

<强> 的appbundle \事件监听\ 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')));
            }
        }
    }
}

总结一下,它非常接近Gopal Joshi回答......
事实上,它只是一些代码清理...... 他和他的回答都在起作用...... 唯一的区别是我的不会出现如下警告:
Method 'methodName()' not foundimport 'import\path\and\name' is never used

Gopal Joshi,如果你碰巧读了我的答案,我问你,我应该验证哪一个?
在这里诚实,大多数学分是你的,所以我将验证你想要的答案......;)

答案 1 :(得分:0)

从控制器获取Sessions的一种方法是:

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

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

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

完整代码

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 {
        [...]
    }
}

<强>更新-1

创建服务以设置会话变量

<强>的appbundle \事件监听\ 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 \资源\配置\ services.yml

  

选项-1

在每个页面加载事件上调用setSession()函数。

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

选项-2

在需要设置会话的地方手动调用setSession()功能。

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

从控制器

调用setSession()功能
$sessionService = $this->get('session_handler');
$sessionService->setSession();