观察者模式
过程:首先我们先创建两个类,Entity.php事件对象, Event事件方法。我们再创建一个APP.php文件用于继承Event这个类。我们在Boostrap.php中去实例化APP这个类,然后调用,往里边写内容。最后我们在controller文件里边创建一个EventController类,给Entity这个类输入数据,最后触发这个事件。
创建一个事件对象:
/**
-
事件对象
-
Class ${解志鑫}
-
@package extend\event
/
class Entity
{
/*- @var string $name
*/
public $name;
/**事件触发者
- @var object $sender
*/
public $sender;
/**事件是否已经被处理,如果handled为true,其他handler不会再接收到通知
- @var bool $handled
*/
public $handled = false;
/**数据
- @var mixed $data
*/
public $data;
}
- @var string $name
事件通知者进行处理:
trait Event
{
/**
* @var array $_events
*/
protected $_events = [];
/**
* Notes:绑定事件
* User: 蜡笔
* Date: 2019/3/18
* Time: 15:48
* @return void
*/
function on($name, $handler, $append = true)
{
$this->_events[ $name ] = isset($this->_events[ $name ]) ? $this->_events[ $name ] : [];
$append ? array_push($this->_events[ $name ],$handler) : array_unshift($this->_events[ $name ],$handler);
}
/**
* Notes:解绑事件
* User: 蜡笔
* Date: 2019/3/18
* Time: 15:48
* @return bool
*/
public function off($name, $handler = null)
{
if (!isset($this->_events[ $name ])) {
return false;
}
//移除所有$name事件的handler
if ($handler === null) {
unset($this->_events[ $name ]);
return true;
} else {
$removed = false;
foreach ($this->_events[ $name ] as $index => $eventHandler) {
if ($eventHandler === $handler) {
unset($this->_events[ $name ][ $index ]);
$removed = true;
}
}
if ($removed) {
$this->_events[ $name ] = array_values($this->_events[ $name ]);
}
return $removed;
}
}
/**
* Notes:是否有handler
* User: 蜡笔
* Date: 2019/3/18
* Time: 15:48
* @return bool
*/
public function hasHandlers($name)
{
if (isset($this->_events[ $name ]) && !empty($this->_events[ $name ])) {
return true;
}
return false;
}
/**
* Notes:触发事件
* User: 蜡笔
* Date: 2019/3/18
* Time: 15:48
* @return void
*/
public function trigger($name, $event = null)
{
if (empty($this->_events[ $name ])) {
return;
}
if ($event === null) {
$event = new Entity();
}
$event->handled = false;
$event->name = $name;
foreach ($this->_events[ $name ] as $handler) {
call_user_func($handler, $event);
//标记已处理,停止后续处理
if ($event->handled) {
return;
}
}
}
下边我们实现以下观察者模式(我们利用上一节讲的DI容器来实现):
我们先创建一个app.php文件:
class App{
use Event;
}
还是在yaf框架的bootstrap.php文件中创建一个方法:
public function _initEvent(\Yaf\Dispatcher $dispatcher)
{
db=newApp();Di::set(′app′,app);
app−>on(′action:run′,function(entity){
Di::get(‘log’)->info(‘事件:数据’,[
‘event’=>entity−>name,′data′=>entity->data
]);
});
app−>on(′action:run′,function(entity){
Di::get('log)->info(‘事件:数据’,[
‘event’=>entity−>name,′data′=>entity->data-1
]);
});
}
在控制器层,我们需要用一个方法执行
创建Event.php文件:
class EventController extends Controller_Abstract{
public function indexAction()
{
$log = Di::get(‘app’);
app−>on(′action:run′,[this,’’]);
//移除所有事件的handler
//$app->off(‘action:run’);
app−>off(′action:run′,[this,‘addition’]);
$entity = new Entity();
$entity->data = time();
app−>trigger(′action:run′,entity);
}
}