Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/248.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用Symfony 4更改用户区域设置?_Php_Symfony_Symfony4_Symfony Translator - Fatal编程技术网

Php 如何使用Symfony 4更改用户区域设置?

Php 如何使用Symfony 4更改用户区域设置?,php,symfony,symfony4,symfony-translator,Php,Symfony,Symfony4,Symfony Translator,我试图用Symfony从数据库中的字段“locale”更改用户区域设置。我阅读了Symfony手册(例如如何粘贴会话),但在我的应用程序中没有任何功能。Translator仍将获取默认区域设置 我创建了监听器、订阅者。。。动态更改区域设置,但由于它们是在防火墙侦听器之前加载的,因此无法更改当前值 我试图更改优先订户,但丢失了用户实体。我试图在控制器中设置区域设置请求,但我认为为时已晚 我不想在URL中添加区域设置 这里是我的订户-侦听器-代码: public function onKernelR

我试图用Symfony从数据库中的字段“locale”更改用户区域设置。我阅读了Symfony手册(例如如何粘贴会话),但在我的应用程序中没有任何功能。Translator仍将获取默认区域设置

我创建了监听器、订阅者。。。动态更改区域设置,但由于它们是在防火墙侦听器之前加载的,因此无法更改当前值

我试图更改优先订户,但丢失了用户实体。我试图在控制器中设置区域设置请求,但我认为为时已晚

我不想在URL中添加区域设置

这里是我的订户-侦听器-代码:

public function onKernelRequest(RequestEvent $event)
{
   $user = $this->tokenStorage->getToken()->getUser();
   $request = $event->getRequest();
   $request->setLocale($user->getLocale());
}  
在订阅服务器中,我添加了:

public static function getSubscribedEvents()
{
   return [
     KernelEvents::REQUEST => [['onKernelRequest', 0]],
   ];
}
这里是我的完整代码:

framework.yml:

default_locale: fr
services.yml:

parameters:
    locale: 'fr'
    app_locales: fr|en|
translation.yml:

framework:
    default_locale: '%locale%'
    translator:
        paths:
            - '%kernel.project_dir%/translations'
        fallbacks:
            - '%locale%'
LocaleSubscriber.php:

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class LocaleSubscriber implements EventSubscriberInterface
{
    private $defaultLocale;

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

    public function onKernelRequest(RequestEvent $event)
    {
        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
            return;
        }
        // try to see if the locale has been set as a _locale routing parameter
        if ($locale = $request->attributes->get('_locale')) {
            $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 static function getSubscribedEvents()
    {
        return [
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            KernelEvents::REQUEST => [['onKernelRequest', 20]],
        ];
    }
}
UserLocaleSubscriber.php

// src/EventSubscriber/UserLocaleSubscriber.php
namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;

/**
 * Stores the locale of the user in the session after the
 * login. This can be used by the LocaleSubscriber afterwards.
 */
class UserLocaleSubscriber implements EventSubscriberInterface
{
    private $session;

    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    public function onInteractiveLogin(InteractiveLoginEvent $event)
    {
        $user = $event->getAuthenticationToken()->getUser();

        if (null !== $user->getLocale()) {
            $this->session->set('_locale', $user->getLocale());
        }
    }

    public static function getSubscribedEvents()
    {
        return [
            SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin',
        ];
    }
}
Ex控制器注释:

/**
     * @Route("/user/locale", name="user_locale", requirements={"_locale" = "%app.locales%"})
     * @Route("/{_locale}/user/locale", name="user_locale_locale", requirements={"_locale" = "%app.locales%"})
     */

如果看不到您使用的完整代码,很难提供帮助

Symfony也有自己的LocaleListener。确保首先执行您的

/**
*@return数组
*/
公共静态函数getSubscribedEvents()
{
返回[
//必须在默认区域设置侦听器之前注册(即优先级高于)
KernelEvents::REQUEST=>[['onKernelRequest',20]],
];
}
  • 使用
    debug:event-kernel.request
    查找防火墙侦听器的优先级
  • 确保在防火墙侦听器之后立即执行
    UserLocaleSubscriber
  • 自动连接translator接口,并手动设置translator区域设置

  • 感谢您的回答,我试图将优先级设置为20、15或17,但令牌存储是空的。Symfony文档中写道:“您可能希望进一步改进此技术,并根据登录用户的用户实体定义区域设置。但是,由于LocaleSubscriber是在FirewallListener之前调用的,FirewallListener负责处理身份验证并在TokenStorage上设置用户令牌,因此您无法访问登录的用户。“即使区域设置存储在会话中,defaultLocale仍然应用。@Alexander将使用类似于此工作的方法:我在会话中丢失区域设置$请求->getSession()->getLocale()为空。结果,翻译器获得了备用语言环境。我如何解决这个问题?
    // src/EventSubscriber/UserLocaleSubscriber.php
    namespace App\EventSubscriber;
    
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpFoundation\Session\SessionInterface;
    use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
    use Symfony\Component\Security\Http\SecurityEvents;
    use Symfony\Contracts\Translation\TranslatorInterface;
    
    /**
     * Stores the locale of the user in the session after the
     * login. This can be used by the LocaleSubscriber afterwards.
     */
    class UserLocaleSubscriber implements EventSubscriberInterface
    {
        private $session;
    
        private $translator;
    
        public function __construct(SessionInterface $session, TranslatorInterface $translator)
        {
            $this->session = $session;
            $this->translator = $translator;
        }
    
        public function onInteractiveLogin(InteractiveLoginEvent $event)
        {
            $user = $event->getAuthenticationToken()->getUser();
    
            if (null !== $user->getLocale()) {
                $this->translator->setLocale($user->getLocale());
            }
        }
    
        public static function getSubscribedEvents()
        {
            return [
                SecurityEvents::INTERACTIVE_LOGIN => ['onInteractiveLogin', 7]
            ];
        }
    }