我想在zendframework2中捕获loggin事件,然后在用户上次登录时更新数据库。
我知道,如果我在模块的onBootstrap(MVCEvent$e)中执行以下操作,我将能够捕获事件等:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUserAuthenticationAdapterAdapterChain',
'authenticate',
function($e)
{
$id = $e->getIdentity();
}
);
这将为我提供用户的Id。然而,令人困惑的是如何从引导程序更新数据库。我的意思是,我无法访问引导程序中的实体管理器,也不知道如何将其传输到那里。实体管理器保存在服务配置文件中。
即getServiceConfig()
'MembersModelWorkerTable' => function($sm) {
$db = $sm->get('doctrine.entitymanager.orm_default');
$table = new ModelMemberTable($db);
return $table;
},
通过以上设置,我可以访问MemberTable类中的实体管理器
因此,一个简单的解决方案是将loggin事件管理器转移到我的**MemberTable类**,我将使用实体管理器更新数据库。
问题,我不确定如何设置:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
我的意思是,我不知道如何将变量$e放入MemberTable类中,以便访问eventManger和sharedManager。
总结;问题有两个方面。
- 如何让实体管理器进入引导程序功能
替代
- 如何将eventManager和共享事件管理器放入一个普通类中,以便在已经包含实体管理器的类中调用事件管理器
好吧,您所要做的就是以这种方式检索服务管理器:
$serviceManager = $e->getApplication()->getServiceManager();
然后让你的实体经理这样:
$entityManager = $serviceManager->get('MembersModelWorkerTable');
它能解决你的问题吗?
第二个问题的答案
要从外部将变量带入闭包,可以使用"use"运算符,如:
function() use ($myVar){
// some code
}
所以,在你的情况下,我会做:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUserAuthenticationAdapterAdapterChain',
'authenticate',
function($e) use ($entityManager){
$id = $e->getIdentity();
}
);
如果您计划在闭包中包含大量代码,我建议将其放入一个单独的类中,并使其可调用。例如,
class YourClosureCode
{
private $entityManager;
public function __construct($eventManager)
{
$this->eventManager = $eventManager;
}
public function __invoke(EventInterface $e)
{
// put your closure code here
}
}
然后在这里稍作修改:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUserAuthenticationAdapterAdapterChain',
'authenticate',
new YourClosureCode($entityManager);
);