Symfony2控制器中的构造函数

时间:2012-06-24 16:34:45

标签: symfony controller

如何在Symfony2控制器中定义构造函数。我想在我的控制器的所有方法中获取登录的用户数据,目前我在我的控制器的每个操作中执行类似的操作以获取登录用户。

$em = $this->getDoctrine()->getEntityManager("pp_userdata");
$user = $this->get("security.context")->getToken()->getUser();

我想在构造函数中执行一次,并在所有操作中使这个登录用户可用

3 个答案:

答案 0 :(得分:12)

对于在每个控制器操作之前执行代码的一般解决方案,您可以将事件侦听器附加到kernel.controller事件,如下所示:

<service id="your_app.listener.before_controller" class="App\CoreBundle\EventListener\BeforeControllerListener" scope="request">
    <tag name="kernel.event_listener" event="kernel.controller" method="onKernelController"/>
    <argument type="service" id="security.context"/>
</service>

然后在BeforeControllerListener中,您将检查控制器是否实现了接口,如果是,则从接口调用方法并传入安全上下文。

<?php

namespace App\CoreBundle\EventListener;

use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\Security\Core\SecurityContextInterface;
use App\CoreBundle\Model\InitializableControllerInterface;

/**
 * @author Matt Drollette <matt@drollette.com>
 */
class BeforeControllerListener
{

    protected $security_context;

    public function __construct(SecurityContextInterface $security_context)
    {
        $this->security_context = $security_context;
    }

    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();

        if (!is_array($controller)) {
            // not a object but a different kind of callable. Do nothing
            return;
        }

        $controllerObject = $controller[0];

        // skip initializing for exceptions
        if ($controllerObject instanceof ExceptionController) {
            return;
        }

        if ($controllerObject instanceof InitializableControllerInterface) {
            // this method is the one that is part of the interface.
            $controllerObject->initialize($event->getRequest(), $this->security_context);
        }
    }
}

然后,您想要让用户始终可用的任何控制器您只需实现该接口并像这样设置用户:

use App\CoreBundle\Model\InitializableControllerInterface;

class DefaultController implements InitializableControllerInterface
{
    /**
     * Current user.
     *
     * @var User
     */
    private $user;

    /**
     * {@inheritdoc}
     */
    public function initialize(Request $request, SecurityContextInterface $security_context)
    {
        $this->user = $security_context->getToken()->getUser();
    }
// ....
}

界面只不过是

namespace App\CoreBundle\Model;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\SecurityContextInterface;

interface InitializableControllerInterface
{
    public function initialize(Request $request, SecurityContextInterface $security_context);
}

答案 1 :(得分:3)

我运行得有点迟了,但在控制器中你可以访问用户:

$this->getUser();

应该从2.1开始工作

答案 2 :(得分:2)

我的方法是:

  1. 创建一个空的Interface InitializableControllerInterface
  2. 制作事件监听器
    namespace ACMEBundle\Event;
    
    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
    
    class ControllerConstructor
    {
        public function onKernelController(FilterControllerEvent $event)
        {
            $controller = $event->getController();
            if (!is_array($controller)) {
                // not a object but a different kind of callable. Do nothing
                return;
            }
    
            $controllerObject = $controller[0];
            if ($controllerObject instanceof InitializableControllerInterface) {
                $controllerObject->__init($event->getRequest());
            }
        }
    }
    
    1. 在您的控制器中添加:
    2. class ProfileController extends Controller implements
              InitializableControllerInterface
      {
      public function __init()
          {
      $this->user = $security_context->getToken()->getUser();
      }
      

      您将能够在每个操作中获得$ this-&gt;用户。

      此致