我是ZF2的新手,并且在应该是一个基本想法方面遇到了一些麻烦.
我正在使用ZfCommons用户模块进行身份验证,它已经安装并且运行正常.
现在我想验证用户实际上是从我的控制器基于此登录的(如何检查用户是否已登录但我无法弄清楚如何注册控制器插件,我当前收到此错误:
Zend\Mvc\Controller\PluginManager::get was unable to fetch or create an instance for ZfcUserAuthentication
Run Code Online (Sandbox Code Playgroud)
我的控制器看起来像这样:
<?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();
}
}
Run Code Online (Sandbox Code Playgroud)
抛出异常是因为您在构造函数中请求插件.由于插件如何绑定到控制器,因此根本无法在控制器的构造函数中使用插件.
背景
创建对象时首先调用构造函数.之前没有其他方法__construct().如果你通过setter方法在这个新实例中注入了一些东西,那么你就无法在构造函数中访问它.
一个代码示例:
$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;
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来很明显,但它正是 Zend Framework 2中控制器和控制器插件管理器正在发生的事情.在创建对象后注入管理器:
$controller = new MySomethingController;
$controller->setPluginManager($plugins);
Run Code Online (Sandbox Code Playgroud)
另请参阅在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();
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以将侦听器附加到控制器的调度,因此将对每个操作进行函数调用,而不是您指定的操作:
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');
}
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以从控制器中删除此逻辑,因此您可以将其重用于多个控制器:
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');
});
}
}
Run Code Online (Sandbox Code Playgroud)
因此,根据您想要的DRY,有很多可能性在构造函数外部访问插件.
| 归档时间: |
|
| 查看次数: |
4864 次 |
| 最近记录: |