观察者模式,事件处理

本文介绍了如何在PHP中实现观察者模式,通过创建事件对象和事件通知者,结合Yaf框架的Dispatcher,注册事件处理器并触发事件。在Controller中执行事件,动态添加和移除事件处理器,并给出具体代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

观察者模式
过程:首先我们先创建两个类,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;
      }

事件通知者进行处理:
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)
{
d b = n e w A p p ( ) ; D i : : s e t ( ′ a p p ′ , db = new App(); Di::set('app', db=newApp();Di::set(app,app);
a p p − > o n ( ′ a c t i o n : r u n ′ , f u n c t i o n ( app->on('action:run',function( app>on(action:run,function(entity){
Di::get(‘log’)->info(‘事件:数据’,[
‘event’=> e n t i t y − > n a m e , ′ d a t a ′ = > entity->name, 'data'=> entity>name,data=>entity->data
]);
});

a p p − > o n ( ′ a c t i o n : r u n ′ , f u n c t i o n ( app->on('action:run',function( app>on(action:run,function(entity){
Di::get('log)->info(‘事件:数据’,[
‘event’=> e n t i t y − > n a m e , ′ d a t a ′ = > entity->name, 'data'=> entity>name,data=>entity->data-1
]);
});

}

在控制器层,我们需要用一个方法执行
创建Event.php文件:
class EventController extends Controller_Abstract{
public function indexAction()
{
$log = Di::get(‘app’);
a p p − > o n ( ′ a c t i o n : r u n ′ , [ app->on('action:run',[ app>on(action:run,[this,’’]);
//移除所有事件的handler
//$app->off(‘action:run’);
a p p − > o f f ( ′ a c t i o n : r u n ′ , [ app->off('action:run',[ app>off(action:run,[this,‘addition’]);
$entity = new Entity();
$entity->data = time();
a p p − > t r i g g e r ( ′ a c t i o n : r u n ′ , app->trigger('action:run', app>trigger(action:run,entity);
}
}

有想学习的同学们可以观看此视频:https://bbs.youkuaiyun.com/topics/392562522 https://edu.youkuaiyun.com/course/play/9933

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值