Php 如何在Symfony中设置用户登录时的区域设置?

Php 如何在Symfony中设置用户登录时的区域设置?,php,symfony,session,authentication,local,Php,Symfony,Session,Authentication,Local,我正在从事一个基于Symfony 2.8的项目。该网页可以使用不同的语言,所选语言存储在会话中。使用区域设置侦听器类,当用户进入页面或登录时,设置正确的区域设置没有问题: class LocaleListener implements EventSubscriberInterface { private $defaultLocale; public function __construct($defaultLocale = 'de') { $this->d

我正在从事一个基于
Symfony 2.8
的项目。该网页可以使用不同的语言,所选语言存储在
会话中。使用
区域设置侦听器
类,当用户进入页面或登录时,设置正确的区域设置没有问题:

class LocaleListener implements EventSubscriberInterface {
    private $defaultLocale;

    public function __construct($defaultLocale = 'de') {
        $this->defaultLocale = $defaultLocale;
    }

    public static function getSubscribedEvents() {
        return array(
            // must be registered before the default Locale listener
            KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
            SecurityEvents::INTERACTIVE_LOGIN => array(array('onSecurityInteractiveLogin', 18)),                
            AuthenticationEvents::AUTHENTICATION_SUCCESS => 'onAuthenticationSuccess',
        );
    }

    public function onKernelRequest(GetResponseEvent $event) {
        $request = $event->getRequest();

        if (!$request->hasPreviousSession()) 
            return;

        if ($locale = $request->attributes->get('_locale')) {            
            // try to see if the locale has been set as a _locale routing parameter    
            $request->getSession()->set('_locale', $locale);
        } else {
            // if no explicit locale has been set on this request, use one from the session            
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {
        // ...get locale from user settings and it info to session...
    }

    public function onAuthenticationSuccess(AuthenticationEvent $event) {
        // ...get locale from user settings and it info to session...
    }
}
这与扩展的with登录侦听器中的代码相同。当用户主动登录时,效果非常好。在这种情况下,
SecurityEvents::INTERACTIVE\u LOGIN
AuthenticationEvents::AUTHENTICATION\u SUCCESS
都会被触发(顺便问一下:两者之间有什么区别)

但是,如果用户登录并访问某个页面,则不会触发这两个事件中的任何一个

当会话过期且
记住我
cookie未过期时,这是一个问题。我在浏览器中刷新页面时遇到了这样的问题,因为我已经几天没有在那台机器上工作了:
memory\u me
cookie仍然处于活动状态,因此用户仍然登录。但是,页面是以默认语言而不是用户语言刷新的,这只有在会话同时过期时才可能

我尚未在配置文件中配置会话生存期,Symfony调试工具栏显示的会话生存期为0。当然,我可以延长它的生命周期,使其比“记住我”选项的生命周期更长。但是,每次用户通过身份验证时,从用户设置中重新读取区域设置将是一个更干净的解决方案

我假设对每个请求都进行了身份验证。通过登录表单(=交互式登录)提交的用户凭据,或通过存储在
memory\u me
cookie中的信息提交。对不对

在这种情况下,我希望在每个请求上都会触发
AuthenticationEvents::AUTHENTICATION\u SUCCESS
事件。但情况似乎并非如此

长话短说:


如何确保用户登录时使用用户设置中的区域设置?

根据我的经验,每次我们发出请求时(如果基于会话的身份验证),symfony都会检查请求是否与任何活动会话匹配(使用一些cookie作为会话标识符或类似的东西)。如果是这样,则会触发
onAuthenticationSuccess
,否则会重定向到登录页面。提交登录表单后,如果用户凭据有效,则对您进行身份验证,并触发安全交互登录

因此,如果凭据在每个请求中都有效,则会触发onAuthenticationSuccess,而只有在成功登录提交时才会触发onSecurityInteractiveLogin。 在任何情况下,成功通过身份验证后,从
onKernelRequest
事件开始,整个内核事件都会将您转发到目标url

因此,我认为问题可能是,当成功完成
onAuthenticationSuccess
时,您实际上会将用户语言填充到会话中,但在触发
onKernelRequest
之后,您会使用此

$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));

如果这是问题,请考虑只在<代码> OnSturyIsActualVoGuIn < /Calp>事件

中设置语言