webman 事件库 webman-event

Tinywan

webman 事件库 webman-event

事件相比较中间件的优势是事件比中间件更加精准定位(或者说粒度更细),并且更适合一些业务场景的扩展。

例如,我们通常会遇到用户注册或者登录后需要做一系列操作,通过事件系统可以做到不侵入原有代码完成登录的操作扩展,降低系统的耦合性的同时,也降低了BUG的可能性。

项目地址

https://github.com/Tinywan/webman-event

安装

composer require tinywan/webman-event

配置

事件配置文件 config/event.php

return [
    // 事件监听
    'listener'    => [],

    // 事件订阅器
    'subscriber' => [],
];

进程启动配置

打开 config/bootstrap.php,加入如下配置:

return [
    // 这里省略了其它配置 ...
    webman\event\EventManager::class,
];

快速开始

定义事件

事件类 LogErrorWriteEvent.php

declare(strict_types=1);

namespace extend\event;

use Symfony\Contracts\EventDispatcher\Event;

class LogErrorWriteEvent extends Event
{
    const NAME = 'log.error.write';  // 事件名,事件的唯一标识

    /** @var array */
    public array $log;

    public function __construct(array $log)
    {
        $this->log = $log;
    }

    public function handle()
    {
        return $this->log;
    }
}

监听事件

return [
    // 事件监听
    'listener'    => [
        \extend\event\LogErrorWriteEvent::NAME  => \extend\event\LogErrorWriteEvent::class,
    ],
];

订阅事件

订阅类 LoggerSubscriber.php

namespace extend\event\subscriber;

use extend\event\LogErrorWriteEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class LoggerSubscriber implements EventSubscriberInterface
{
    /**
     * @desc: 方法描述
     * @return array|string[]
     */
    public static function getSubscribedEvents()
    {
        return [
            LogErrorWriteEvent::NAME => 'onLogErrorWrite',
        ];
    }

    /**
     * @desc: 触发事件
     * @param LogErrorWriteEvent $event
     */
    public function onLogErrorWrite(LogErrorWriteEvent $event)
    {
        // 一些具体的业务逻辑
        var_dump($event->handle());
    }
}

事件订阅

return [
    // 事件订阅
    'subscriber' => [
        \extend\event\subscriber\LoggerSubscriber::class,
    ],
];

事件触发器

触发 LogErrorWriteEvent 事件。

$error = [
    'errorMessage' => '错误消息',
    'errorCode' => 500
];
EventManager::trigger(new LogErrorWriteEvent($error),LogErrorWriteEvent::NAME);

执行结果

打印结果

License

This project is licensed under the Apache 2.0 license.

3152 4 0
4个评论

walkor

感谢分享。
项目地址好像错了

小杰

老大,大佬,事件非常好用易用,要是再有个可以开发插件用hook就齐全了。

  • 暂无评论
yzh52521

我使用的laravel

namespace support;

use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;

/**
 *  class Event
 * @package support
 *
 *  Strings methods
 * @method static \Illuminate\Events\Dispatcher dispatch($event)
 */
class Event
{
    /**
     * @var Dispatcher
     */
    protected static $instance=null;

    /**
     * @return Dispatcher|null
     */
    public static function instance()
    {
        if (!static::$instance) {
            $container        = new Container;
            static::$instance = new Dispatcher($container);
            $eventsList       = config('events');
            if (isset($eventsList['listener']) && !empty($eventsList['listener'])) {
                foreach ($eventsList['listener'] as $event => $listener) {
                    if (is_string($listener)) {
                        $listener = implode(',', $listener);
                    }
                    foreach ($listener as $l) {
                        static::$instance->listen($event, $l);
                    }
                }
            }
            if (isset($eventsList['subscribe']) && !empty($eventsList['subscribe'])) {
                foreach ($eventsList['subscribe'] as  $subscribe) {
                    static::$instance->subscribe($subscribe);
                }
            }
        }
        return static::$instance;
    }

    /**
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public static function __callStatic($name, $arguments)
    {
        return self::instance()->{$name}(... $arguments);
    }

}

配置
config/events.php

return [
    'listener'  => [
        app\events\Test::class => [
            \app\listeners\TestListeners::class,
        ],
    ],
    'subscribe' => [
        \app\subscribes\TestSubscribe::class,
    ],
];

事件类:Test

namespace app\events;

class Test
{
    public  $data = [];

    public function __construct($data)
    {
        $this->data = $data;
    }
}

监听类

namespace app\listeners;

use app\events\Test;

class TestListeners
{
    public function __construct()
    {
    }

    /**
     * 处理事件
     * @return void
     */
    public function handle(Test $event)
    {
        // 控制台打印
        var_dump('listener');
        var_dump($event->data);
    }
}

订阅类

namespace app\subscribes;

use app\events\Test;

class TestSubscribe
{
    public function handleTest(Test $event)
    {
        var_dump('subscribe');
        var_dump($event);
    }

    public function subscribe($events)
    {
        $events->listen(
            Test::class,
            [TestSubscribe::class, 'handleTest']
        );
    }

helpers.php 增加

/**
 * 事件
 * @param $event
 */
function event($event)
{
    Event::dispatch($event);
}

调用触发事件

event(new Test('event data'));

  • 小杰 2021-12-20

    这个也容易,还有定义助手函数

  • Tinywan 2021-12-20

    我不用 laravel 的,向symfony看齐

  • 大好时光 2022-02-21

    使用这个出现A facade root has not been set.

= - =

在 eloquent model 里面已经有集成 laravel 的 event dispatcher,可以通过 model::created(closure $func) 监听,是否可以将 event 的集成方式也加入 webman 官方文档呢?

  • Tinywan 2022-01-31

    webman 只做最基础的

  • = - = 2022-03-17

    棒,可以提交到插件中心吗

  • yzh52521 2022-03-17

    已提交 在审核中

  • = - = 2022-03-17

    好的,感谢大佬贡献

  • = - = 2022-03-17

    @yzh52521 为啥事件没有基于 illuminate/events:^9.0 。看到版本锁定为 ^8.0,无法使用最新的。

    Your requirements could not be resolved to an installable set of packages.
    
      Problem 1
        - Root composer.json requires yzh52521/webman-event ^1.0 -> satisfiable by yzh52521/webman-event[1.0.0].
        - yzh52521/webman-event 1.0.0 requires illuminate/events ^8.0 -> found illuminate/events[v8.0.0, ..., v8.83.5] but it conflicts with your root composer.json require (^9.5).
    
    Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
    You can also try re-running composer require with an explicit version constraint, e.g. "composer require yzh52521/webman-event:*" to figure out if any version is installable, or "composer require yzh52521/webman-event:^2.1" if you know which you need.
    
    Installation failed, reverting ./composer.json and ./composer.lock to their original content.
  • = - = 2022-03-17

    https://www.workerman.net/plugin/28 @yzh52521 我包想降个版本安装你的包,还要降低 php 8.0 版本到 7.3 版本。┭┮﹏┭┮

  • yzh52521 2022-03-18

    php8.0是可以使用的 现在已经兼容php8.1 illuminate/events 9.X

  • = - = 2022-03-18

    好的。谢谢大佬

年代过于久远,无法发表评论

Tinywan

11230
积分
0
获赞数
0
粉丝数
2020-01-14 加入
🔝