jf/event

PSR-14 事件系统

维护者

详细信息

gitlab.com/jfphp/jfEvent

主页

源代码

安装: 222

依赖: 0

建议者: 0

安全: 0

星标: 0

分支: 0

2.0.1 2023-07-29 15:50 UTC

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帮助实现 SplSubjectPsr\EventDispatcher\EventDispatcherInterfacePsr\EventDispatcher\ListenerProviderInterface 接口的特质。
jf\event\TEvent实现 IEvent 接口的特质。
jf\event\TEventDispatcher实现 Psr\EventDispatcher\EventDispatcherInterfacePsr\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)