2

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

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

现在我想验证用户实际上是基于此从我的控制器登录的(如何检查用户是否已登录但我无法弄清楚如何注册控制器插件,我目前收到此错误:

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();
    }
}
4

2 回答 2

9

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

背景

创建对象时首先调用构造函数。之前没有调用其他方法__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 上的控制器中注入插件管理器的代码。因此:不幸的是,您无法访问构造函数中的插件。

选择

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

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 程度,有很多可能性可以在构造函数之外访问插件。

于 2013-06-20T08:22:26.110 回答
0

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

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

$this->zfcUserAuthentication()->getIdentity()
于 2013-06-20T04:11:24.160 回答