jf / event
2.0.1
2023-07-29 15:50 UTC
Requires
- psr/event-dispatcher: ^1.0
This package is auto-updated.
Last update: 2024-09-29 18:27:14 UTC
README
PSR-14 事件系统。
安装
Composer
本项目使用 Composer 作为依赖管理器,可以按照项目官方文档中的说明进行安装:Composer。
使用此包管理器安装 jf/event
包,需要执行以下命令:
composer require jf/event
依赖
项目安装时,将自动安装以下依赖项:
包 | 版本 |
---|---|
psr/event-dispatcher | ^1.0 |
版本控制
本项目可以使用 git
进行安装。首先需要克隆项目,然后安装依赖项。
git clone git@gitlab.com:joaquinfq/jfEvent.git
cd jfEvent
composer install
可用文件
类
名称 | 描述 |
---|---|
jf\event\Event | 用于通用事件的简单类。 |
jf\event\Manager | 简单的事件管理器。 |
jf\event\Proxy | 通用事件,用作代理,在需要将事件直接传递给观察者的 update 时的 subject 对象。 |
接口
名称 | 描述 |
---|---|
jf\event\IEvent | 用于发出事件的接口。 |
jf\event\IObserver | 事件观察者的接口。 |
jf\event\ISubject | 事件发射器的接口。 |
特质
名称 | 描述 |
---|---|
jf\event\TDispatcher | 帮助实现 SplSubject 、Psr\EventDispatcher\EventDispatcherInterface 和 Psr\EventDispatcher\ListenerProviderInterface 接口的特质。 |
jf\event\TEvent | 实现 IEvent 接口的特质。 |
jf\event\TEventDispatcher | 实现 Psr\EventDispatcher\EventDispatcherInterface 和 Psr\EventDispatcher\ListenerProviderInterface 接口的特质。 |
jf\event\TObservers | 管理事件观察者列表。 |
jf\event\TSplSubject | 实现 SplSubject 接口的特质。 |
jf\event\TStoppable | 实现 Psr\EventDispatcher\StoppableEventInterface 接口的特质。 |
演示
demos/events.php
演示了如何使用 SPL 和 jf/event
中的事件和观察者。
<?php
use jf\event\Event;
use jf\event\IObserver;
use jf\event\Manager;
use jf\event\TSplSubject;
require_once __DIR__. '/../vendor/autoload.php';
/**
* Trait para simplificar la creación de los observadores.
*/
trait TLogObserver
{
/**
* @inheritdoc
*/
public function update(SplSubject $subject) : void
{
global $counter;
if ($subject instanceof LogEvent || $subject instanceof LogEventSplSubject)
{
printf("%d %s(%s -- %s)\n", $counter++, static::class, $subject::class, $subject->message);
}
else if ($subject instanceof Manager)
{
// Se entra aquí si se usa `$manager->notify()`.
printf("%d %s(%s)\n", $counter++, static::class, $subject::class);
}
}
}
/**
* Evento para registar una traza.
*/
trait TLogEvent
{
/**
* Constructor de la clase.
*
* @param string $message Mensaje de la traza.
*/
public function __construct(public readonly string $message)
{
}
}
/**
* Evento para registar una traza.
*/
class LogEvent extends Event
{
use TLogEvent;
}
/**
* Evento para registar una traza.
*/
class LogEventSplSubject implements SplSubject
{
use TLogEvent;
use TSplSubject;
}
/**
* Observador para detectar la solicitud de registro de traza y mostrarla por pantalla
* pero podría almacenarse en disco, base de datos, etc., usando otros observadores.
*
* Usando IObserver
*/
readonly class LogObserver implements IObserver
{
use TLogObserver;
/**
* @inheritdoc
*/
public function observedEvents() : array
{
return [ LogEvent::class, LogEventSplSubject::class ];
}
}
/**
* Observador para detectar la solicitud de registro de traza y mostrarla por pantalla
* pero podría almacenarse en disco, base de datos, etc., usando otros observadores.
*
* Usando SplObserver
*/
readonly class LogSplObserver implements SplObserver
{
use TLogObserver;
}
//----------------------------------------------------------------------------------------------------------------------
// Inicio del script
//----------------------------------------------------------------------------------------------------------------------
// Opción 1: Usando el manager y cpm la configuración de eventos y observadores.
//----------------------------------------------------------------------------------------------------------------------
$counter = 1;
$manager = new Manager(
[
LogEvent::class => [ LogObserver::class, LogSplObserver::class ],
LogEventSplSubject::class => [ LogObserver::class, LogSplObserver::class ]
]
);
$manager->dispatch(new LogEvent('Opción 1'));
$manager->dispatch(new LogEventSplSubject('Opción 1'));
$manager->notify(); // No se ha usado `attach` así que no ejecuta ningún observador SPL
//----------------------------------------------------------------------------------------------------------------------
// Resultado por pantalla:
//----------------------------------------------------------------------------------------------------------------------
// 1 LogObserver(LogEvent -- Opción 1)
// 2 LogSplObserver(LogEvent -- Opción 1)
// 3 LogObserver(LogEventSplSubject -- Opción 1)
// 4 LogObserver(LogEventSplSubject -- Opción 1)
// 5 LogSplObserver(LogEventSplSubject -- Opción 1)
// 6 LogObserver(jf\event\Manager) <-- notify()
// 7 LogSplObserver(jf\event\Manager) <-- notify()
// 8 LogObserver(jf\event\Manager) <-- notify()
// 9 LogSplObserver(jf\event\Manager) <-- notify()
//----------------------------------------------------------------------------------------------------------------------
// Las lineas 3 y 4 se repiten por pasar el nombre de una clase IEvent y llamarse a observedEvents().
// Al llamar a `notify()` se llamarán a tantos observadores como nombres de clases de observadores se pasaron, en este
// caso 2 para LogEvent y 2 para LogEventSplSubject.
// Si en vez de pasar nombres de clases sino instancias se eliminan algunas de esas duplicidades.
//----------------------------------------------------------------------------------------------------------------------
// Opción 2: Agregando manualmente los eventos y sus observadores.
// Usando `attach` el manager trabaja solamente con IObserver para poder obtener los nombres de los eventos a escuchar.
// El resto debe llamarse con `nofity()`.
//----------------------------------------------------------------------------------------------------------------------
$manager = new Manager();
$manager->attach(new LogObserver());
$manager->attach(new LogSplObserver()); // No observará eventos al no ser IEvent, se usa con `notify()`
$manager->dispatch(new LogEvent('Opción 2'));
$manager->dispatch(new LogEventSplSubject('Opción 2'));
$manager->notify(); // Ejecuta los observadores SPL agregados con attach.
//----------------------------------------------------------------------------------------------------------------------
// Resultado por pantalla:
//----------------------------------------------------------------------------------------------------------------------
// 10 LogObserver(LogEvent -- Opción 2)
// 11 LogObserver(LogEventSplSubject -- Opción 2)
// 12 LogObserver(jf\event\Manager) <-- notify()
// 13 LogSplObserver(jf\event\Manager) <-- notify()
//----------------------------------------------------------------------------------------------------------------------
// Opción 3: Usando SPL
//----------------------------------------------------------------------------------------------------------------------
$subject = new LogEventSplSubject('Opción 3');
$subject->attach(new LogSplObserver());
$subject->attach(new LogObserver());
$subject->notify();
//----------------------------------------------------------------------------------------------------------------------
// Resultado por pantalla:
//----------------------------------------------------------------------------------------------------------------------
// 14 LogSplObserver(LogEventSplSubject -- Opción 3)
// 15 LogObserver(LogEventSplSubject -- Opción 3)