VOOZH about

URL: https://deepwiki.com/hypervel/event/5.2-wildcard-listeners

⇱ Wildcard Listeners | hypervel/event | DeepWiki


Loading...
Menu

Wildcard Listeners

Purpose: This document explains how to use wildcard event patterns to register listeners that match multiple events, the internal matching mechanism, storage architecture, and performance considerations for cross-cutting concerns.

For information about registering standard event listeners, see Creating Event Listeners. For general listener management and priority handling, see ListenerProvider and ListenerData.


Overview

Wildcard listeners enable a single listener to handle multiple events that match a pattern. Instead of registering the same listener for user.created, user.updated, and user.deleted individually, you can register it once for user.* to capture all user-related events. This feature is particularly useful for cross-cutting concerns like logging, auditing, or monitoring.

The wildcard matching system uses asterisk (*) as a glob-style pattern matcher, leveraging Hyperf's Str::is() method for flexible pattern evaluation.

Sources: src/ListenerProvider.php1-153 src/EventDispatcher.php349-354


Wildcard Pattern Syntax

The system supports standard glob-style wildcard patterns:

PatternMatchesExample Events
user.*Any event starting with user.user.created, user.updated, user.deleted
*.createdAny event ending with .createduser.created, post.created, order.created
order.*.confirmedEvents with order. prefix and .confirmed suffixorder.payment.confirmed, order.shipping.confirmed
*All eventsAny event in the system

The matching is performed using Str::is($pattern, $eventName) which provides case-sensitive glob matching.

Sources: src/ListenerProvider.php38-41 src/ListenerProvider.php116


Registering Wildcard Listeners

Wildcard listeners are registered the same way as regular listeners through the EventDispatcher::listen() method. The system automatically detects wildcard patterns by checking for the asterisk character.

Basic Registration


With Priority

Wildcard listeners support priority just like regular listeners:


Sources: src/EventDispatcher.php116-144 src/ListenerProvider.php59-74


Internal Storage Architecture

The ListenerProvider maintains separate storage arrays for regular and wildcard listeners to optimize retrieval performance.

Storage Structure Diagram


The on() method uses isWildcardEvent() to determine storage location:

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


Listener Retrieval and Matching Process

When an event is dispatched, getListenersForEvent() retrieves both direct matches and wildcard matches, merges them, and returns them sorted by priority.

Retrieval Flow Diagram


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


Matching Algorithm Implementation

The matching process is divided into two phases within getListenersForEvent():

Phase 1: Direct Listener Matching


This retrieves exact matches from the listeners array.

Phase 2: Wildcard Pattern Matching


This iterates through all wildcard patterns, using Str::is($pattern, $eventName) to test each pattern against the event name.

Phase 3: Merge and Sort


The method merges both result sets and caches them for subsequent dispatches of the same event. The getListenersUsingCondition() helper method handles the priority sorting:

  1. Filter listeners by the provided condition src/ListenerProvider.php129-131
  2. Flatten the nested arrays src/ListenerProvider.php131
  3. Sort by priority (descending), then by index (ascending) src/ListenerProvider.php139-142
  4. Return the sorted listener callables src/ListenerProvider.php143

Sources: src/ListenerProvider.php33-44 src/ListenerProvider.php127-144


Priority Handling with Wildcards

Wildcard listeners participate in the same priority system as regular listeners. When multiple listeners (both direct and wildcard) match an event, they are sorted by priority, with ties broken by registration order.

Priority Resolution Example


The sorting occurs in getListenersUsingCondition() where listeners are sorted by:

  1. Priority (descending)
  2. Index (ascending, for stable ordering)

Sources: src/ListenerProvider.php139-142 src/ListenerData.php12-14


Performance Considerations

Caching Mechanism

The ListenerProvider implements result caching to avoid repeated pattern matching:


The cache is invalidated whenever listeners are added or removed src/ListenerProvider.php64 src/ListenerProvider.php89

Wildcard Matching Complexity

OperationComplexityNotes
First dispatchO(W × M)W = number of wildcard patterns, M = matching complexity
Cached dispatchO(1)Direct cache lookup
Pattern matchingO(M)Depends on Str::is() implementation
SortingO(N log N)N = total matching listeners

Best Practices

  1. Specific Patterns: Use specific patterns (user.created.*) over broad patterns (*) to reduce unnecessary matches
  2. Limit Wildcards: Excessive wildcard listeners can slow down the first dispatch of each unique event
  3. Monitor Cache: The cache grows with each unique event dispatched; monitor memory in high-volume systems
  4. Avoid Deep Nesting: Patterns like a.*.b.*.c.* require more complex matching

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


Checking for Wildcard Listeners

The system provides methods to check if wildcard listeners are registered:

EventDispatcher Methods


The hasWildcardListeners() method delegates to ListenerProvider::hasWildcard():


This iterates through all registered wildcard patterns and tests each against the provided event name.

Sources: src/EventDispatcher.php343-354 src/ListenerProvider.php103-122


Common Use Cases

1. Audit Logging


2. Domain-Specific Monitoring


3. Metrics Collection


4. Multi-Pattern Listeners


5. Debugging and Development


Sources: src/EventDispatcher.php116-144 src/ListenerProvider.php67-73


Forgetting Wildcard Listeners

Wildcard listeners can be removed using the forget() method. The system automatically detects wildcard patterns and removes them from the correct storage:


The implementation in ListenerProvider::forget():


Note that forgetting invalidates the entire listener cache to ensure consistency.

Sources: src/ListenerProvider.php87-98 src/EventDispatcher.php335-338


Implementation Details Summary

ComponentFileLinesPurpose
wildcards arraysrc/ListenerProvider.php18Stores wildcard pattern listeners
isWildcardEvent()src/ListenerProvider.php149-152Detects wildcard patterns
hasWildcard()src/ListenerProvider.php113-122Checks for matching wildcards
getListenersForEvent()src/ListenerProvider.php25-54Retrieves and matches listeners
getListenersUsingCondition()src/ListenerProvider.php127-144Filters and sorts listeners
hasWildcardListeners()src/EventDispatcher.php351-354Public API for wildcard check

Sources: src/ListenerProvider.php1-153 src/EventDispatcher.php1-618