将对象从分派侦听器传递给控制器

时间:2014-06-13 13:43:37

标签: php zend-framework2

所以我在Module.php中有一个dispatch事件监听器,它从数据库中检索用户对象,并用它设置布局变量。 我想访问控制器中的同一个对象。我怎么能通过呢?

public function onBootstrap($e)
    {

        $eventManager       = $e->getApplication()->getEventManager();
        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($eventManager);
        $app = $e->getParam('application');
        $app->getEventManager()->attach('dispatch', array($this, 'setPortfolioLayout'));

    }

    /**
     * This event will set $user variable in layout when it's active
     *
     * @param MvcEvent $e
     */
    public function setPortfolioLayout(MvcEvent $e)
    {

        $matchedRoute = $e->getRouteMatch();

        if($matchedRoute->getParam('isPortfolio')) {

            $em = $e->getApplication()->getServiceManager()->get('Doctrine\ORM\EntityManager'); /** @var ObjectManager $em */
            $user = $em->getRepository('Application\Entity\User')->findOneBy(['login' => $matchedRoute->getParam('login')]);

            if(! $user) {
                $e->getResponse()->setStatusCode(404); return;
            }

            $viewModel = $e->getViewModel();
            $viewModel->setVariable('user', $user);
            $viewModel->setTemplate('layout/portfolio');

            $matchedRoute->setParam('user', $user);

        }
    }

我尝试过设置RouteMatch参数 - 不是最好的地方,而且在Controller中不可见。 监听器中有一个$e->getController()方法。我应该为每个期望它的控制器添加一个特殊的方法来设置用户对象(添加接口特性等)吗?

1 个答案:

答案 0 :(得分:2)

您可以非常轻松地访问在控制器中设置的布局参数:

$user = $this->layout()->user;

另外,您提到您无法访问控制器中的RouteMatch参数,但实际上您可以:

$user = $this->getEvent()->getRouteMatch()->getParam('user');

此外,如果"用户"这是特定控制器的硬依赖关系,我认为将它设置到ServiceManager中是没有错的(在调度之前,所以你需要在你的例子中增加你的调度监听器的优先级)并使它成为一个硬依赖(构造函数注入)控制器。然后,您为控制器创建一个工厂,构建控制器,如:

return new MyController($sm->get('active-user'));

在这种情况下,您需要小心确保您有足够的控制措施,以确保在不成为活跃用户'服务(或任何你称之为的服务)。