listeners[$eventName][] = $listener; } public function dispatch(string $eventName, mixed $payload = null): void { if (! $this->hasListeners($eventName)) { return; } foreach ($this->listeners[$eventName] as $listener) { $listener($payload); } } public function remove(string $eventName, callable $listener): void { if (! $this->hasListeners($eventName)) { return; } $this->listeners[$eventName] = array_filter( $this->listeners[$eventName], static fn (callable $existing) => $existing !== $listener ); } public function hasListeners(string $eventName): bool { return ! empty($this->listeners[$eventName]); } }