VOOZH about

URL: https://deepwiki.com/hypervel/event/2.2-listenerprovider-and-listenerdata

⇱ ListenerProvider and ListenerData | hypervel/event | DeepWiki


Loading...
Menu

ListenerProvider and ListenerData

Purpose and Scope

This document explains how listeners are stored, organized, and retrieved in the event system. The ListenerProvider class manages the listener registry, while ListenerData encapsulates listener metadata. Together, they form the storage and retrieval layer that sits between listener registration and event dispatch.

For information about how listeners are registered through configuration and annotations, see Creating Event Listeners. For details on how the EventDispatcher uses the ListenerProvider during event dispatch, see EventDispatcher.


Architecture Overview

The ListenerProvider and ListenerData components form a two-tier storage system where ListenerData objects encapsulate listener metadata, and ListenerProvider organizes these objects for efficient retrieval.


Sources: src/ListenerProvider.php1-153 src/ListenerData.php1-22


ListenerData Structure

ListenerData is a simple data object that encapsulates three pieces of information about a listener: the event it listens to, the listener callable, and its priority.

PropertyTypeDescription
$eventstringThe event name or class this listener handles
$listenerarray|callable|stringThe listener callable (closure, class name, or array)
$priorityintPriority value (higher = executed first)

The class extends Hyperf\Event\ListenerData and defines a DEFAULT_PRIORITY constant (inherited from the parent class) used when no priority is specified.


Sources: src/ListenerData.php9-22


Storage Organization

The ListenerProvider maintains three internal arrays to organize listeners efficiently:

Storage Arrays

ArrayPurposeKey FormatValue Format
$listenersExact event name matchesEvent class name or stringArray of ListenerData objects
$wildcardsWildcard pattern matchesPattern string (e.g., "user.*")Array of ListenerData objects
$listenersCachePerformance cacheEvent class name or stringFlattened array of listener callables

The separation between $listeners and $wildcards enables efficient lookup: exact matches are retrieved directly by array key, while wildcard patterns require iteration and string matching.


Sources: src/ListenerProvider.php16-20 src/ListenerProvider.php59-74 src/ListenerProvider.php149-152


Listener Registration

The on() method registers a listener with the provider, creating a ListenerData object and storing it in the appropriate array.

Method Signature

on(string $event, array|callable|string $listener, int $priority = ListenerData::DEFAULT_PRIORITY): void

Registration Process

  1. Cache Invalidation: Clears $listenersCache to ensure fresh results on next retrieval
  2. ListenerData Creation: Wraps the listener information in a ListenerData object
  3. Storage Selection: Determines whether to use $listeners or $wildcards based on presence of *
  4. Array Append: Appends the ListenerData to the appropriate array

Sources: src/ListenerProvider.php59-74


Listener Retrieval and Priority Ordering

The getListenersForEvent() method retrieves all applicable listeners for an event and returns them ordered by priority.

Retrieval Algorithm

The method follows a multi-step process:

  1. Event Name Extraction: Converts event object to class name if necessary
  2. Cache Lookup: Checks $listenersCache for previously computed results
  3. Exact Match Retrieval: Filters $listeners array for matching event names
  4. Wildcard Match Retrieval: Filters $wildcards array using pattern matching
  5. Merge and Cache: Combines results and stores in cache
  6. Priority Queue Construction: Builds SplPriorityQueue with proper ordering

Priority Queue Construction

The method uses SplPriorityQueue from Hyperf to order listeners. The queue is populated using a negative index strategy:

  • Each listener's index (position in the merged array) is multiplied by -1
  • This ensures that when priorities are equal, listeners maintain insertion order
  • Higher priority values are executed first (standard queue behavior)

Example Priority Ordering:

ListenerPriorityIndexQueue Priority
Listener A10000 (inserted with -0)
Listener B1001-1 (inserted with -1)
Listener C502-2 (inserted with -2)

Queue extraction order: Listener C (priority 50), Listener A (priority 100, index 0), Listener B (priority 100, index 1)

Sources: src/ListenerProvider.php25-54 src/ListenerProvider.php127-144


Wildcard Event Matching

Wildcard listeners use glob-style pattern matching to subscribe to multiple events with a single registration.

Pattern Matching Mechanism

The provider uses Hyperf\Stringable\Str::is() for pattern matching, which supports:

  • * - matches any sequence of characters
  • ? - matches a single character

Wildcard Detection and Retrieval


Wildcard Methods

MethodPurpose
isWildcardEvent(string $event)Checks if an event name contains * during registration
hasWildcard(string $event)Checks if any wildcard pattern matches the given event name

Sources: src/ListenerProvider.php38-41 src/ListenerProvider.php67-71 src/ListenerProvider.php113-122 src/ListenerProvider.php149-152


Caching Mechanism

The provider implements a simple but effective caching strategy to avoid redundant listener retrieval and sorting operations.

Cache Lifecycle


Cache Invalidation Triggers

The cache is cleared (set to empty array []) when:

  1. A new listener is registered via on()
  2. Listeners are removed via forget()

This ensures the cache never serves stale data after registration changes.

Performance Impact

OperationWithout CacheWith Cache
First dispatch of event XFilter + Sort + Match wildcardsFilter + Sort + Match wildcards
Second dispatch of event XFilter + Sort + Match wildcardsArray lookup
Third dispatch of event XFilter + Sort + Match wildcardsArray lookup

Sources: src/ListenerProvider.php20 src/ListenerProvider.php30-44 src/ListenerProvider.php64 src/ListenerProvider.php89


API Methods

The ListenerProvider implements the Hypervel\Event\Contracts\ListenerProvider interface, which extends PSR-14's ListenerProviderInterface.

Method Reference

MethodReturn TypeDescription
getListenersForEvent(object|string $event)iterableRetrieves and orders listeners for an event
on(string $event, array|callable|string $listener, int $priority)voidRegisters a listener
all()arrayReturns the raw $listeners array
forget(string $event)voidRemoves all listeners for an event
has(string $event)boolChecks if event has exact or wildcard listeners
hasWildcard(string $event)boolChecks if event has wildcard listeners

Method Implementations

getListenersForEvent()

Returns an SplPriorityQueue containing listener callables ordered by priority and insertion order. This is the primary method called by EventDispatcher during event dispatch.

all()

Returns the raw $listeners array without processing. This method exposes exact-match listeners but excludes wildcards. Used by EventDispatcher::getRawListeners().

forget()

Removes all listeners for a specific event and invalidates the cache. Handles both exact matches and wildcard patterns based on the presence of * in the event name.

has()

Performs a comprehensive check for listeners:

  1. Checks $listeners array for exact match
  2. Checks $wildcards array for exact pattern match
  3. Iterates wildcards to check for pattern matches

hasWildcard()

Only checks if any wildcard pattern matches the event name. Does not check exact-match listeners.

Sources: src/ListenerProvider.php1-153 src/Contracts/ListenerProvider.php1-40


Integration with EventDispatcher

The EventDispatcher uses the ListenerProvider through the getListeners() method, which delegates to getListenersForEvent().


Sources: src/ListenerProvider.php25-54 src/Contracts/Dispatcher.php36


Contract Compliance

The ListenerProvider implements both the custom Hypervel\Event\Contracts\ListenerProvider interface and PSR-14's ListenerProviderInterface.

Interface Hierarchy


The custom contract extends PSR-14 to add:

  • Support for string event names (not just objects)
  • Registration capabilities (on())
  • Query capabilities (all(), has(), hasWildcard())
  • Removal capabilities (forget())

Sources: src/Contracts/ListenerProvider.php1-40 src/ListenerProvider.php14