我也知道php和nodejs,在javascript中我们有异步编程,所以我理解了事件的含义。但我在Yii和Zend 2中看到事件并且也使用它们,但我可以不明白它的含义,它在php中是如何工作的以及它究竟在做什么?
答案 0 :(得分:12)
事件是带有名称的回调函数的抽象。
通常,我们会将其定义为$eventName => $listener
,其中$listener
是$eventName
的回调函数
再次 - 要记住的核心要点是事件是回调函数。没什么。
它们之间的唯一区别是我们如何调用它们。
在bootstrap步骤中使用其必需参数定义事件,但在没有参数的情况下按需调用。虽然回调函数是使用参数调用的,但只有
考虑这个例子,
<?php
$eventManager = new EventManager();
$eventManager->attach('my_event', function(){
print_r(func_get_args());
}, array('foo', 'bar'));
正如我们刚刚定义的一个事件,我们会调用,
$eventManager->trigger('my_event');
这将输出:Array([0] => [foo], [1] => [bar]
由于我们大多数人都熟悉JavaScript甚至驱动的架构,因此值得一提的是其常用用法的一个例子:
var a = document.getElementsByTagName('a')[0];
a.onclick = function(event) { // <-- We define an event with the event argument
event.preventDefault();
alert('A element was clicked');
}
a.click(); // <-- but we invoke it without arguments
// or If you want a Jquery
$("a").click(function(event){
event.preventDefault();
alert('A element was clicked');
});
$("a").click();
由于在PHP中我们没有这种事件驱动的性质,我们可以用我们自己的类替换它来管理事件并充分利用它。
虽然事件让很多人感到困惑,但它们非常有用。
假设您拥有内容管理系统(CMS),您的用户可以决定如何处理404
错误。说,他们可以处理
1)显示空白页面
2)重定向到/
3)显示自定义消息
没有事件你就必须这样做,比如
if ($router->isMatched($request)){
//do dispatch etc
} else {
// Here you start handling 404 errors
switch($config->read('404_way_handle')){
case 'show_blank':
die();
break;
case 'show_msg':
echo 'Some custom message';
break;
case 'redirect':
// do redirect
break;
}
}
通过一个事件,您可以简化可读性并使代码更易于维护:
if ($router->isMatched($request)){
// do dispatch
} else {
$eventManager->trigger('404_handler');
}
虽然404_handler
本身看起来像
$eventManager->attach('404_handler', function(){
switch($config->read('404_way_handle')){
case 'show_blank':
die();
break;
case 'show_msg':
echo 'Some custom message';
break;
case 'redirect':
// do redirect
break;
}
}, $config);
1)事件提高了可读性,这对未来很有意义
2)事件确实遵循单一责任原则,因为您只需将$eventManager
注入需要它的类,而回调函数可能会破坏它或可能引入<强>全球状态(对单元测试来说不好)。
3)有不同类型的逻辑 - 模板逻辑,业务逻辑,错误处理程序逻辑,数据访问逻辑等。事件通过解耦业务(或其他类型)逻辑来简化您的应用程序逻辑从配置逻辑开始,最终得到清晰的应用程序逻辑。
如果您想知道它们如何在Zend Framework 2中工作,您可以观看此lecture(即使您不熟悉Zend Framework 2也要观看它)
与MVC相关的体系结构中的事件
由于你一直在讨论框架,值得一提的是,MVC-related
架构中也可能存在事件。由于事件是回调函数,因此您可以在类似MVC的体系结构中抽象常见的boostrap
事件,就像这样。
$mvcEvent->on(MVC_EVENT::ROUTE_MATCH, function(){
$mvcEvent->on(MVC_EVENT::DISTPATCH, function($content){
echo $mvcEvent->trigger(MVC_EVENT::RENDER, $content);
});
});
注意:在纯MVC理论中,根本没有事件。他们确实充当帮助者,但是再次 - 在框架中,您可以抽象它们并称之为“事件”。
答案 1 :(得分:0)
本文帮助我在ZF2中下载了EventManager:
事件管理器是框架的组件,允许您挂接应用程序中的命名事件。
框架中存在一组现有的命名事件,例如控制器中的dispatch事件。您也可以根据应用程序的目的创建自己的。这是第一步。 然后,您附加(或倾听)这些事件。当它们触发或被触发时,您的代码会询问事件的上下文并在需要时作出响应。
参考:http://www.maltblue.com/tutorial/zend-framework-2-event-manager-a-gentle-introduction