事件相比較中間件的優(yōu)勢(shì)是事件比中間件更加精準(zhǔn)定位(或者說(shuō)粒度更細(xì)),并且更適合一些業(yè)務(wù)場(chǎng)景的擴(kuò)展。
例如,我們通常會(huì)遇到用戶注冊(cè)或者登錄后需要做一系列操作,通過(guò)事件系統(tǒng)可以做到不侵入原有代碼完成登錄的操作擴(kuò)展,降低系統(tǒng)的耦合性的同時(shí),也降低了BUG的可能性。
https://github.com/Tinywan/webman-event
composer require tinywan/webman-event
事件配置文件
config/event.php
return [
// 事件監(jiān)聽(tīng)
'listener' => [],
// 事件訂閱器
'subscriber' => [],
];
進(jìn)程啟動(dòng)配置
打開(kāi) 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'; // 事件名,事件的唯一標(biāo)識(shí)
/** @var array */
public array $log;
public function __construct(array $log)
{
$this->log = $log;
}
public function handle()
{
return $this->log;
}
}
return [
// 事件監(jiān)聽(tīng)
'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: 觸發(fā)事件
* @param LogErrorWriteEvent $event
*/
public function onLogErrorWrite(LogErrorWriteEvent $event)
{
// 一些具體的業(yè)務(wù)邏輯
var_dump($event->handle());
}
}
事件訂閱
return [
// 事件訂閱
'subscriber' => [
\extend\event\subscriber\LoggerSubscriber::class,
],
];
觸發(fā) LogErrorWriteEvent
事件。
$error = [
'errorMessage' => '錯(cuò)誤消息',
'errorCode' => 500
];
EventManager::trigger(new LogErrorWriteEvent($error),LogErrorWriteEvent::NAME);
執(zhí)行結(jié)果
This project is licensed under the Apache 2.0 license.
我使用的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;
}
}
監(jiān)聽(tīng)類
namespace app\listeners;
use app\events\Test;
class TestListeners
{
public function __construct()
{
}
/**
* 處理事件
* @return void
*/
public function handle(Test $event)
{
// 控制臺(tái)打印
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);
}
調(diào)用觸發(fā)事件
event(new Test('event data'));
在 eloquent model 里面已經(jīng)有集成 laravel 的 event dispatcher,可以通過(guò) model::created(closure $func) 監(jiān)聽(tīng),是否可以將 event 的集成方式也加入 webman 官方文檔呢?
@yzh52521 為啥事件沒(méi)有基于 illuminate/events:^9.0 。看到版本鎖定為 ^8.0,無(wú)法使用最新的。
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.
http://m.wtbis.cn/plugin/28 @yzh52521 我包想降個(gè)版本安裝你的包,還要降低 php 8.0 版本到 7.3 版本。┭┮﹏┭┮
感謝分享。
項(xiàng)目地址好像錯(cuò)了