16

我有一个注销侦听器,我想在其中设置一条显示注销确认消息的闪存消息。

namespace Acme\MyBundle\Security\Listeners;

use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

class LogoutListener implements LogoutSuccessHandlerInterface
{
  private $security;  

  public function __construct(SecurityContext $security)
  {
    $this->security = $security;
  }

  public function onLogoutSuccess(Request $request)
  {
    $request->get('session')->getFlashBag()->add('notice', 'You have been successfully been logged out.');

    $response = new RedirectResponse('login');
    return $response;
  }
}

这是我的 services.yml(与此相关):

logout_listener:
   class:  ACME\MyBundle\Security\Listeners\LogoutListener
   arguments: [@security.context]

这会产生错误:

Fatal error: Call to a member function getFlashBag() on a non-object

如何在这种情况下设置 flashBag 消息?

另外,如何访问路由器,以便生成 url(通过 $this->router->generate('login'))而不是传入硬编码的 url?

分辨率说明

要让 flash 工作,您必须告诉您的 security.yml 配置不要在注销时使会话无效;否则,会话将被破坏,您的闪存将永远不会出现。

logout:
    path: /logout
        success_handler: logout_listener
        invalidate_session: false
4

2 回答 2

29

您应该将会话和路由器的服务注入 LogoutListener 并使用它们来执行这些任务。这是在 yml 中执行此操作的方法:

logout_listener: 
class: ACME\MyBundle\Security\Listeners\LogoutListener 
arguments: [@security.context, @router, @session]

然后在你的课上你写:

class LogoutListener implements LogoutSuccessHandlerInterface
{
    private $security;
    private $router;
    private $session;

    public function __construct(SecurityContext $security, Router $router, Session $session)
    {
        $this->security = $security;
        $this->router = $router;
        $this->session = $session;
    }
    [...]

当你现在想使用会话时,你可以说:

$this->session->getFlashBag()->add('notice', 'You have been successfully been logged out.');

并且以同样的方式,您可以使用路由器服务来生成路由。

于 2012-11-12T17:35:32.657 回答
1

您可以通过服务容器获取 Session 对象(以及任何其他服务):

$session = $ServiceContainer->get('session');
$session->setFlash('notice', 'Message');

您可以通过不同方式访问服务容器的方式:

  • 从控制器或任何容器感知类:只需使用 $this->get('session');
  • 从服务:您必须像 Aldo 所说的那样注入服务容器对象
于 2012-11-12T18:00:45.327 回答