-
Notifications
You must be signed in to change notification settings - Fork 2
Migration Guide
This guide covers two migrations:
-
From
initphp/event-emitter(any 1.x) →initphp/events:^2.0— the standalone package has been merged into this one and is now deprecated. -
From
initphp/events:^1.0→initphp/events:^2.0— the same high-levelEventsfacade, now bundling the low-levelEventEmitterprimitive.
In both cases the upgrade path is intentionally gentle: your existing code keeps compiling.
{
"require": {
- "initphp/event-emitter": "^1.0"
+ "initphp/events": "^2.0"
}
}initphp/events:^2.0 declares a Composer
replace for
initphp/event-emitter: *, so Composer will refuse to install both
side-by-side. No need to manually remove the old package — composer update will handle it.
composer update initphp/event-emitter initphp/eventssrc/aliases.php is autoloaded by Composer's files directive. It
creates two class aliases:
// effectively:
class_alias(InitPHP\Events\EventEmitter::class, 'InitPHP\\EventEmitter\\EventEmitter');
class_alias(InitPHP\Events\EventEmitterInterface::class, 'InitPHP\\EventEmitter\\EventEmitterInterface');That means existing code like this does not need to change:
use InitPHP\EventEmitter\EventEmitter; // old namespace
use InitPHP\EventEmitter\EventEmitterInterface; // old namespace
$bus = new EventEmitter();
$bus->on('e', $listener);
$bus->emit('e');It resolves to the new classes via the alias. You can ship the upgrade without touching application code.
When you next touch each file, switch to the canonical namespace:
- use InitPHP\EventEmitter\EventEmitter;
+ use InitPHP\Events\EventEmitter;
- use InitPHP\EventEmitter\EventEmitterInterface;
+ use InitPHP\Events\EventEmitterInterface;The alias is intended as a transition aid; treat it as deprecated and
plan to clean up use statements before a future major release of this
package removes the shim.
The 1.x line of the standalone initphp/event-emitter package shipped
with a bug in EventEmitter::emit(): it passed the whole listeners
array (rather than each individual listener) to
call_user_func_array, so listeners never actually ran. That bug is
fixed in initphp/events:^2.0.
Practical consequences:
- If you had
emit()calls that looked like they worked but never actually invoked your listeners, they will start firing now. - Any code that silently relied on listeners not running is now broken.
- Audit every
EventEmitter::emit()call site before deploying. If you see something like "no idea why this listener was registered — must have been dead code", run it — there's a chance it was never reachable under 1.x.
This is the one place where the migration is not purely additive.
Once your codebase imports only InitPHP\Events\*, the aliases in
src/aliases.php are unused — but harmless. They will be removed in a
future major release of this package; clean up your use statements
before then to avoid a hard break.
composer require initphp/events:^2.0 is the upgrade. The high-level
Events facade keeps the same method names and the
same call shapes, so most code keeps compiling unchanged. But the
package fixes two long-standing bugs whose visible behaviour shifts,
and the facade's default priority changes — read the BC-break notes
below before deploying.
Additive — does not break anything if you ignore it:
-
Bundled low-level
EventEmitter— previously only available as the standaloneinitphp/event-emitterpackage. -
EventEmitterInterfaceis now defined inside this package. -
composer replaceofinitphp/event-emitter, so Composer refuses to install both packages side-by-side. -
Backwards-compatibility aliases for the old
InitPHP\EventEmitter\*namespace. - New high-level surface on
Event/Events:once(),off(),removeAllListeners(),clearDebug(), andgetEmitter(). - New singleton lifecycle on the facade:
getInstance()(now public; wasprotectedin 1.x),setInstance($event), andreset()— finally usable test hooks. - New low-level method:
EventEmitter::clearOnceListeners(?string)(also added toEventEmitterInterface).
The 1.x line of EventEmitter::emit() had a bug where the entire
listeners array (rather than each individual listener) was passed to
call_user_func_array. Listeners silently never ran.
The fix in 2.0 means previously-silent listeners will now actually
execute. Audit every EventEmitter::emit() call site — if your old
code relied on listeners not firing, that is now broken.
The 1.x EventEmitter::listeners() had a bug: ksort() was applied to
the wrong array level (the inner per-priority listener list, which is
already numerically indexed [0, 1, 2, …]), instead of the outer
priority map. The effect was that listeners ran in registration
order, regardless of their $priority.
In 2.0, priority order is honoured: lower numeric priority runs first; within the same priority, FIFO by registration order.
- If your 1.x code happened to register listeners in ascending priority order (the obvious style), the visible behaviour does not change.
- If you registered them in some other order and depended on the registration-order behaviour, the invocation order will flip.
This change affects both Events::trigger() and EventEmitter::emit()
— anything that goes through EventEmitter::listeners(). Background:
Listeners & Priorities.
In 1.x, the default for Event::on() (and therefore Events::on())
was PRIORITY_LOW (200). In 2.0, the default is PRIORITY_NORMAL
(100) — matching EventEmitter::on() and intuition.
- No effect if you always passed an explicit priority.
-
Effect if you mixed default-priority
on()calls with explicitPRIORITY_LOWones: previously they shared a bucket; in 2.0 the defaults now run before the explicitPRIORITY_LOWones. - The fix: pass
Event::PRIORITY_LOWexplicitly to restore the old positioning, or audit your registrations and decide what you actually meant.
1.x's Event::trigger() pulled listeners via
EventEmitter::listeners() (which includes one-shot listeners) but
never cleaned them up — so one-shot listeners registered through
Event / Events (which… 1.x didn't expose, but if you reached into
Event->getEmitter() you'd see this) fired on every trigger.
2.0's Event::trigger() cleans up one-shot listeners in a
try/finally block — they fire at most once, even if the chain
is stopped by a false return or a listener throws. The cleanup is
inseparable from trigger().
If you ship your own implementation of EventEmitterInterface, you
must add a clearOnceListeners(?string $event = null): void method
in 2.0. Reference implementation:
public function clearOnceListeners($event = null)
{
if ($event === null) {
// drop every one-shot listener for every event
} elseif (!is_string($event)) {
throw new \InvalidArgumentException('$event must be a string or null.');
} else {
// drop one-shot listeners only for the named event
}
}The bundled EventEmitter of course implements it.
composer require initphp/events:^2.0| Source state | Target | Code changes required |
|---|---|---|
Only initphp/events:^1.0
|
initphp/events:^2.0 |
Verify priority-ordering and Event::on() default-priority changes (steps 2–4 above). |
Only initphp/event-emitter:^1.0
|
initphp/events:^2.0 |
Use the alias (no source changes). Verify the emit() and priority-ordering fixes. If you ship a custom EventEmitterInterface implementation, add clearOnceListeners(). |
| Both packages installed |
initphp/events:^2.0 only |
composer remove initphp/event-emitter (or rely on replace — Composer will reject the combo). |
Mix of InitPHP\EventEmitter\* and InitPHP\Events\* use statements |
Same | Swap use statements when you touch each file; both work today. |
The standalone initphp/event-emitter was a single-class library that
solved a problem already addressed by initphp/events. Maintaining two
packages with nearly identical surface meant two release lines, two
issue trackers, and double the change-log overhead — for a feature set
that fits comfortably in one package. Merging both into
initphp/events:^2.0 keeps a single canonical source of truth and lets
the two APIs (the facade and the
emitter) share infrastructure cleanly.
- Home — overview of the consolidated package.
-
EventEmitter— the API formerly known asinitphp/event-emitter. - Troubleshooting — what to do if listeners that worked under 1.x stop firing (or start firing).
initphp/events · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Core APIs
Practical
Reference