-
Notifications
You must be signed in to change notification settings - Fork 2
FAQ
Short answers to common questions. The longer-form material lives in the linked reference pages.
Events is a static facade over a single shared Event instance;
EventEmitter is the instantiable, dependency-injectable sibling.
Events facade |
EventEmitter |
|
|---|---|---|
| Registry | one global, shared | one per instance |
on() returns |
the shared Event (chainable) |
$this (chainable) |
once() available |
✅ | ✅ |
Stops chain on false return |
✅ | — |
| Arguments | varargs | array |
| Simulate / debug mode | ✅ | — |
Removal API (off / removeAllListeners) |
✅ | ✅ |
| Reset between tests/jobs | Events::reset() |
new instance |
See Events facade vs EventEmitter
for the full comparison.
- Use
Eventswhen you want WordPress-style global hooks, ergonomic varargs at the call site, and the optional simulate / debug instrumentation. - Use
EventEmitterwhen you want a plain object you can build per-request, dependency-inject, or hand to a service — without reaching for global state.
once(), off(), and removeAllListeners() exist on both APIs, so
they are not a reason to pick one over the other.
You can use both side-by-side — they do not share state.
Yes. Listeners with a lower numeric priority fire first; within the same priority bucket, registration order (FIFO) wins. The named constants are aliases for integers:
-
PRIORITY_HIGH = 10— runs first -
PRIORITY_NORMAL = 100— default -
PRIORITY_LOW = 200— runs last
Events::on('e', fn() => print("late\n"), Events::PRIORITY_LOW);
Events::on('e', fn() => print("first\n"), Events::PRIORITY_HIGH);
Events::trigger('e');
// → first
// → late1.x had a bug that silently ignored
$priorityand dispatched in registration order. That is fixed in 2.0 — see Listeners & Priorities and the Migration Guide.
No. Both APIs lowercase the event name before storing or looking it up,
so 'User.Registered', 'user.registered', and 'USER.REGISTERED'
reference the same event. Choose one convention and stick with it.
// Events facade — varargs
Events::trigger('order.placed', $order, 'web', 2);
// EventEmitter — array
$bus->emit('order.placed', [$order, 'web', 2]);Listeners always receive the arguments unpacked positionally:
function (array $order, string $source, int $version) { /* … */ }Return strict false from a listener attached via the
Events facade; trigger() will return false and
skip the remaining listeners. EventEmitter::emit() does not
short-circuit on false — see Stopping Propagation
for the patterns that work there.
Yes — pass the payload by reference if it is an array or object, and mutate it in place:
Events::on('user.before_save', function (array &$user) {
$user['email'] = strtolower($user['email']);
});
$user = ['email' => 'JANE@example.com'];
Events::trigger('user.before_save', $user);
echo $user['email']; // jane@example.comObjects are passed by handle in PHP — mutations propagate without any ampersand.
Yes. It will fire twice. Re-registering does not deduplicate.
EventEmitter::removeListener() removes all instances of that
callable in one call.
No. The codebase predates and does not target
PSR-14 (Event Dispatcher). If you
need PSR-14 specifically, build a thin adapter over EventEmitter (a
listener provider + dispatcher pair is ~30 lines).
PHP's standard model has no shared-memory threads in user code, so
"thread-safe" is not meaningful here. The library is not safe to use
from multiple parallel coroutines that share an Event/EventEmitter
instance unless your runtime serialises access.
The 2.x line targets PHP 5.6+, and the runtime contract is verified
in CI (PHP 5.6 / 7.0 / 7.1 / 7.2 are linted to make sure the source
parses; PHP 7.3 / 7.4 / 8.0 / 8.1 / 8.2 / 8.3 / 8.4 run the full
PHPUnit suite). The 1.x line was tied to PHP 7.x; the README in the
legacy initphp/event-emitter repo claimed 5.4+.
Yes — initphp/events is the active package. The split
initphp/event-emitter
repository is deprecated; its contents now ship inside this
package. See Migration Guide.
github.com/InitPHP/Events/issues.
Include a minimal reproduction, your PHP version, and the package
version (composer show initphp/events).
Use github.com/orgs/InitPHP/discussions. Bug reports go in Issues; design questions, "how do I do X", and broader conversation go in Discussions.
Yes. On the low-level emitter directly, or on the facade via
Events::getEmitter():
$bus->listeners(); // every listener across every event
$bus->listeners('user.login'); // just that event
Events::getEmitter()->listeners('user.login'); // same, via the facadeThe returned array is already merged across both the regular and one-shot registries and sorted in dispatch order (priority + FIFO).
initphp/events · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Core APIs
Practical
Reference