【问题标题】:ZF2 Controller PluginZF2 控制器插件
【发布时间】:2023-03-19 20:42:01
【问题描述】:

我是 ZF2 的新手,在基本概念方面遇到了一些问题。

我正在使用 ZfCommons 用户模块进行身份验证,它已安装并且运行正常。

现在我想验证用户实际上是基于此从我的控制器登录的(How to check if the user is logged in 但我不知道如何注册控制器插件,我目前收到此错误:

Zend\Mvc\Controller\PluginManager::get was unable to fetch or create an instance for ZfcUserAuthentication

我的控制器如下所示:

<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController as AbstractActionController;
use Zend\View\Model\ViewModel as ViewModel;

class IndexController extends AbstractActionController
{

    public function __construct()
    {
        $plugin = $this->plugin('ZfcUserAuthentication');

    }

    public function indexAction()
    {
        return new ViewModel();
    }

    public function testAction()
    {
        return new ViewModel();
    }
}

【问题讨论】:

    标签: zend-framework2


    【解决方案1】:

    抛出异常是因为您在构造函数中请求插件。由于插件与控制器的绑定方式,根本不可能在控制器的构造函数中使用插件。

    背景

    创建对象时首先调用构造函数。在__construct() 之前没有调用其他方法。如果你通过 setter 方法在这个新实例中注入一些东西,那么你无法在构造函数中访问 this

    代码示例:

    $obj = new MyClass();
    $obj->setFoo('foo');
    
    class MyClass()
    {
      protected $foo;
    
      public function __construct()
      {
        var_dump($this->foo); // null!
      }
    
      public function setFoo($foo)
      {
        $this->foo = $foo;
      }
    }
    

    这似乎很明显,但 正是 Zend Framework 2 中的控制器和控制器插件管理器正在发生的事情。管理器在对象创建后注入:

    $controller = new MySomethingController;
    $controller->setPluginManager($plugins);
    

    另请参阅 Github 上的 code which injects the plugin manager in the controller。因此:很遗憾,您无法访问构造函数中的插件。

    替代方案

    您可以通过任何操作访问插件:

    class IndexController extends AbstractActionController
    {
        public function indexAction()
        {
            // This works!
            $plugin = $this->plugin('ZfcUserAuthentication');
    
            return new ViewModel();
        }
    
        public function testAction()
        {
            // This works too!
            $plugin = $this->plugin('ZfcUserAuthentication');
    
            return new ViewModel();
        }
    }
    

    您还可以将侦听器附加到控制器的调度中,以便为每个操作进行函数调用,而不是您指定的操作:

    use Zend\Mvc\MvcEvent;
    
    class IndexController extends AbstractActionController
    {
        public function indexAction()
        {
           return new ViewModel();
        }
    
        public function testAction()
        {
            return new ViewModel();
        }
    
        protected function attachDefaultListeners()
        {
            parent::attachDefaultListeners();
    
            $events = $this->getEventManager();
            $events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'checkUserIdentity'));
        }
    
        public function checkUserIdentity()
        {
            // This works!
            // It is called for both indexAction() and testAction()
            $plugin = $this->plugin('ZfcUserAuthentication');
        }
    }
    

    你甚至可以从控制器中移除这个逻辑,这样你就可以为多个控制器重复使用它:

    class Module
    {
        public function onBootstrap($e)
        {
            $app = $e->getApplication();
            $em  = $app->getEventManager()->getSharedManager();
    
            $em->attach('MyModule\Controller\MyController', MvcEvent::EVENT_DISPATCH, function($e) {
                $controller = $e->getController();
    
                // This works!
                $plugin = $controller->plugin('ZfcUserAuthentication');
            });
        }
    }
    

    所以,根据你想要的 DRY 程度,有很多可能性可以在构造函数之外访问插件。

    【讨论】:

    • 所以使用最干燥的方法并将代码放在 module.php 文件中 - 我需要为每个控制器执行 $em->attach 吗,或者我可以为所有控制器执行它 - 在我的应用程序,所有东西都需要保护,因此必须将侦听器附加到应用程序中的每个控制器是很愚蠢的。
    • 没关系,再看一下文档就知道我可以在服务管理器中做到这一点。
    【解决方案2】:

    根据文档,您可以使用以下内容

    $this->zfcUserAuthentication()->hasIdentity()
    
    $this->zfcUserAuthentication()->getIdentity()
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多