首先,PHP中没有事件
事件是回调函数及其名称的抽象。
通常,我们将它们定义为$eventName => $listener
, where $listener
是一个回调函数$eventName
事件和常规回调函数有什么区别?
再次强调 - 要记住的核心点是事件是回调函数。而已。
它们之间唯一的区别是我们如何调用它们。
An event is defined on bootstrap step with its required arguments, but invoked on demand without arguments. While the callback function is invoked with arguments and only
考虑这个例子,
<?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 有关!
由于我们大多数人都熟悉 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');
}
while 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)有不同类型的逻辑 - 模板逻辑、业务逻辑、错误处理程序逻辑、数据访问逻辑等。 事件简化通过将业务(或其他类型)逻辑与其应用程序逻辑解耦配置逻辑,以便您最终获得清晰的应用程序逻辑。
你可以看这个lecture如果您想知道它们在 Zend Framework 2 中如何工作(即使您不熟悉 Zend Framework 2,也请观看)