purpleharmonie/event-system

Purpleharmonie Event System 是一个灵活且强大的 PHP 应用程序事件分发库。它提供了 PSR-14 事件分派标准的稳健实现,以及针对高级用例的附加功能。

1.0.0 2024-08-04 21:08 UTC

This package is not auto-updated.

Last update: 2024-09-30 20:03:44 UTC


README

目录

  1. 简介
  2. 特性
  3. 安装
  4. 基本用法
  5. 高级概念
  6. 与依赖注入集成
  7. 最佳实践
  8. API 参考

简介

Purpleharmonie Event System 是一个灵活且强大的 PHP 应用程序事件分发库。它提供了 PSR-14 事件分派标准的稳健实现,以及针对高级用例的附加功能。

特性

  • 符合 PSR-14 的事件分派器
  • 支持事件订阅者
  • 优先级事件监听者
  • 可停止事件
  • 事件验证
  • 中间件支持
  • 条件事件分派
  • 异步事件处理(钩子)
  • PSR-3 记录器集成
  • 轻松与依赖注入容器集成

安装

您可以使用 Composer 安装 Purpleharmonie Event System

composer require purpleharmonie/event-system

基本用法

以下是一个如何使用事件系统的简单示例

use Purpleharmonie\EventSystem\EventDispatcher;
use Purpleharmonie\EventSystem\ListenerProvider;

// Create the listener provider and event dispatcher
$listenerProvider = new ListenerProvider();
$eventDispatcher = new EventDispatcher($listenerProvider);

// Define an event
class UserRegisteredEvent
{
    public function __construct(public string $username) {}
}

// Add a listener
$listenerProvider->addListener(UserRegisteredEvent::class, function(UserRegisteredEvent $event) {
    echo "User registered: {$event->username}\n";
});

// Dispatch an event
$event = new UserRegisteredEvent('john_doe');
$eventDispatcher->dispatch($event);

高级概念

事件订阅者

事件订阅者允许您在单个类中组合多个事件监听器

use Purpleharmonie\EventSystem\Interface\EventSubscriberInterface;

class UserSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            UserRegisteredEvent::class => [
                ['onUserRegistered', 10],
                ['sendWelcomeEmail', 5]
            ]
        ];
    }

    public function onUserRegistered(UserRegisteredEvent $event): void
    {
        echo "User registered: {$event->username}\n";
    }

    public function sendWelcomeEmail(UserRegisteredEvent $event): void
    {
        echo "Sending welcome email to {$event->username}\n";
    }
}

// Usage
$listenerProvider->addSubscriber(new UserSubscriber());

优先级监听者

您可以设置监听器的优先级以控制它们的执行顺序

$listenerProvider->addListener(ExampleEvent::class, function(ExampleEvent $event) {
    echo "High priority listener\n";
}, 10);

$listenerProvider->addListener(ExampleEvent::class, function(ExampleEvent $event) {
    echo "Low priority listener\n";
}, -10);

可停止事件

可停止事件允许您防止事件进一步传播

use Purpleharmonie\EventSystem\StoppableEvent;

class StoppableExampleEvent extends StoppableEvent
{
    public $message;

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

$listenerProvider->addListener(StoppableExampleEvent::class, function(StoppableExampleEvent $event) {
    echo "First listener\n";
    $event->stopPropagation();
});

$listenerProvider->addListener(StoppableExampleEvent::class, function(StoppableExampleEvent $event) {
    echo "This won't be called if propagation is stopped\n";
});

事件验证

您可以实现 ValidatableEventInterface 以向您的事件添加自定义验证逻辑

use Purpleharmonie\EventSystem\Interface\ValidatableEventInterface;

class UserRegisteredEvent implements ValidatableEventInterface
{
    public function __construct(public string $username, public string $email) {}

    public function isValid(): bool
    {
        return !empty($this->username) && filter_var($this->email, FILTER_VALIDATE_EMAIL);
    }
}

// Add a custom validator
$eventDispatcher->addValidator(UserRegisteredEvent::class, function(UserRegisteredEvent $event) {
    return strlen($event->username) >= 3;
});

中间件

中间件允许您在事件到达监听器之前拦截和修改事件

$eventDispatcher->addMiddleware(function($event) {
    if ($event instanceof UserRegisteredEvent) {
        $event->username = strtolower($event->username);
    }
    return $event;
});

条件事件分派

ConditionalEventDispatcher 允许您为事件分派添加条件

$conditionalDispatcher = new ConditionalEventDispatcher($eventDispatcher);
$conditionalDispatcher->addCondition(UserRegisteredEvent::class, function(UserRegisteredEvent $event) {
    return strlen($event->username) > 3;
});

异步事件处理

您可以通过实现 AsyncEventDispatcherInterface 来异步处理事件

use Purpleharmonie\EventSystem\Interface\AsyncEventDispatcherInterface;

class ExampleAsyncDispatcher implements AsyncEventDispatcherInterface
{
    public function dispatchAsync(object $event, array $context = [])
    {
        // Queue the event for asynchronous processing
        return uniqid('job_');
    }

    public function getAsyncStatus($jobIdentifier): string
    {
        // Check and return the status of the async job
    }
}

$asyncDispatcher = new ExampleAsyncDispatcher();
$eventDispatcher->setAsyncDispatcher($asyncDispatcher);

// Dispatch asynchronously
$jobId = $eventDispatcher->dispatchAsync($event, ['source' => 'web_signup']);

与依赖注入集成

以下是如何将事件系统与依赖注入容器集成的示例

// services.php
$services->set('example_subscriber', ExampleSubscriber::class)
    ->asGlobal(true)
    ->asShared(true);

$services->set('logger', function ($container) {
    return new Logger('event_dispatcher');
})
->implements(LoggerInterface::class)
->asGlobal(true)
->asShared(true);

$services->set('listener_provider', function ($container) {
    $logger = $container->get('logger');
    return new ListenerProvider($logger);
})
->implements(ListenerProviderInterface::class)
->asGlobal(true)
->asShared(true);

$services->set('event_dispatcher', EventDispatcher::class)
    ->autowire()
    ->asGlobal(true)
    ->asShared(true);

最佳实践

  1. 保持事件小巧,专注于应用程序的单个方面。
  2. 使用事件订阅者来组织相关监听器。
  3. 使用优先级确保监听器的正确执行顺序。
  4. 对关键事件实施验证以确保数据完整性。
  5. 使用中间件处理适用于多个事件的横切关注点。
  6. 考虑使用异步事件处理耗时的操作。

API 参考

对于完整的 API 参考,请使用类似 phpDocumentor 的工具生成 API 文档。