initphp/events
Composer 安装命令:
composer require initphp/events
包简介
Events (Hook) library — bundles the EventEmitter primitive previously distributed as initphp/event-emitter.
README 文档
README
A small, dependency-free event / hook library for PHP. Ships both a
high-level dispatcher with WordPress-style do_action-like semantics
(stop the chain when a listener returns false, simulate mode, debug
log) and a plain low-level EventEmitter you can instantiate and pass
around like any other object.
Heads-up — v2.0 fixes a long-standing priority-ordering bug. In 1.x, listeners ran in the order they were registered, not in the order their priorities asked for. v2.0 makes priority honour its name. If your 1.x code happened to register listeners in ascending priority order, the visible behaviour does not change; if it didn't, please re-read Priorities and ordering and the v2.0 changelog.
At a glance
Events— a static facade backed by a lazily-built singleton. Convenient for application-wide hooks where threading a dispatcher through every layer is overkill.Event— the high-level dispatcher itself. Adds priority-ordered dispatch with a "returnfalsestops the chain" contract, plus optional simulate and debug modes. Use this directly when you want a dispatcher you own.EventEmitter— the low-level primitive. Plainon/once/emit/removeListener. No simulate, no debug, no short-circuit. Use this when you need a dispatcher with the smallest possible surface — or when you are migrating from the deprecatedinitphp/event-emitterpackage (the legacy\InitPHP\EventEmitter\*class names still work via a BC alias).
Everything is in a single PSR-4 namespace (InitPHP\Events\) and has
zero runtime dependencies.
Requirements
| Requirement | Version |
|---|---|
| PHP | >= 5.6 (runtime); PHP >= 7.3 to run the test suite (PHPUnit 9.6) |
| Extensions | none |
| Composer dependencies | none |
Installation
composer require initphp/events
If you are coming from initphp/event-emitter, replace your dependency
— initphp/events declares a Composer replace for it and ships a
class alias so the old fully-qualified names still resolve. See
Migration for details.
Quick start
require __DIR__ . '/vendor/autoload.php'; use InitPHP\Events\Events; Events::on('helloTrigger', function (): void { echo 'Hello World' . PHP_EOL; }, 100); Events::on('helloTrigger', function (): void { echo 'Hi, World' . PHP_EOL; }, 99); Events::trigger('helloTrigger');
Output:
Hi, World
Hello World
The listener registered with priority 99 runs before the one with
priority 100 — lower numeric value means runs first. The three
named constants Events::PRIORITY_HIGH (10), Events::PRIORITY_NORMAL
(100), and Events::PRIORITY_LOW (200) exist for readability.
Passing arguments to listeners
Events::on('greet', function (string $name, string $me): void { echo "Hi {$name}. I am {$me}." . PHP_EOL; }, 99); Events::trigger('greet', 'World', 'John'); // Hi World. I am John.
Stopping the chain
A listener that returns boolean false halts the chain — subsequent
listeners are not invoked and trigger() itself returns false. This
is the same convention as WordPress's apply_filters short-circuit:
Events::on('save', function ($payload) { if (!isValid($payload)) { return false; // stops the chain } }, 10); Events::on('save', function ($payload): void { persist($payload); // never runs if validation returned false }, 20); if (!Events::trigger('save', $payload)) { // at least one listener vetoed the operation }
Working with Event directly
If you prefer a dispatcher you instantiate and pass around (easier to
test, easier to scope, no global state), use Event:
use InitPHP\Events\Event; $dispatcher = new Event(); $dispatcher ->on('user.registered', function ($user): void { sendWelcomeEmail($user); }) ->on('user.registered', function ($user): void { trackSignup($user); }, Event::PRIORITY_LOW); // run last $dispatcher->trigger('user.registered', $user);
Event and Events expose the same surface — Events::on(...) simply
forwards to a shared Event instance.
Working with the low-level EventEmitter
For libraries that want the smallest possible surface, the underlying emitter is also public:
use InitPHP\Events\EventEmitter; $emitter = new EventEmitter(); $emitter->on('hello', function (string $name): void { echo "Hello {$name}!" . PHP_EOL; }, 99); $emitter->once('hello', function (string $name): void { echo "Hi {$name}, this only fires once." . PHP_EOL; }, 10); $emitter->emit('hello', ['World']); $emitter->emit('hello', ['World']);
Differences from Event:
emit()returnsvoid(no short-circuit onfalse).- Listener arguments come in as a single array, not as varargs.
- No simulate or debug mode.
- No singleton.
EventEmitter is what Event is built on. The same instance is
reachable via $dispatcher->getEmitter() if you ever need both
high-level dispatch and low-level emit on the same listener registry.
Priorities and ordering
PRIORITY_HIGH = 10 ← runs first
PRIORITY_NORMAL = 100
PRIORITY_LOW = 200 ← runs last
Rules:
- Lower numeric priority runs first. The names are about importance (high-priority work runs early); the numbers are about position.
- Within the same priority, listeners run in registration order (FIFO).
- Priority is global per-event — once-listeners and regular listeners are merged into a single priority-sorted queue when an event fires.
- Event names are matched case-insensitively:
on('User.Created')andemit('user.created')see the same listener.
See docs/04-priorities-and-ordering.md
for the full ordering contract, including how once() interacts with
the priority queue.
One-shot listeners, removal, and cleanup
$dispatcher->once('boot', $listener); // fires at most once $dispatcher->off('boot', $listener); // removes a specific listener $dispatcher->removeAllListeners('boot'); // wipes one event $dispatcher->removeAllListeners(); // wipes every event
The once() contract is honoured even when the chain is stopped by a
false return — a one-shot listener that runs (or that would have
run, but for a short-circuit earlier in the queue) is dropped after
the trigger completes. See
docs/05-once-and-removal.md.
Simulate mode and debug log
Event (and therefore Events) carry two opt-in instrumentation
modes:
$dispatcher = new InitPHP\Events\Event(); $dispatcher->setSimulate(true); // listeners are not invoked; trigger() still returns true $dispatcher->setDebugMode(true); // each trigger() appends {start, end, event} to the log $dispatcher->trigger('checkout.complete', $order); $dispatcher->getDebug(); // [['start' => ..., 'end' => ..., 'event' => 'checkout.complete']] $dispatcher->clearDebug(); // empty the log
See docs/06-debug-and-simulate.md.
Public API
| Class | Purpose |
|---|---|
InitPHP\Events\Events |
Static facade; thin shim over a shared Event instance. |
InitPHP\Events\Event |
High-level dispatcher (priority, short-circuit, simulate, debug). |
InitPHP\Events\EventEmitter |
Low-level primitive (on / once / emit / removeListener / clearOnceListeners). |
InitPHP\Events\EventEmitterInterface |
Contract that EventEmitter implements. |
| Method | Class | Purpose |
|---|---|---|
trigger(string $name, ...$arguments): bool |
Event · Events |
Dispatch with priority + short-circuit semantics. |
on(string, callable, int $priority = PRIORITY_NORMAL): self |
Event · Events · EventEmitter |
Register a listener. |
once(string, callable, int $priority = PRIORITY_NORMAL): self |
Event · Events · EventEmitter |
Register a one-shot listener. |
off(string, callable): self |
Event · Events |
Remove a specific listener (alias for removeListener). |
removeListener(string, callable): void |
EventEmitter |
Remove a specific listener. |
removeAllListeners(?string = null): self/void |
Event · Events · EventEmitter |
Wipe one event, or every event. |
emit(string, array $args = []): void |
EventEmitter |
Low-level dispatch (no short-circuit). |
clearOnceListeners(?string = null): void |
EventEmitter |
Drop one-shot listeners without invoking them. |
listeners(?string = null): array |
EventEmitter |
Inspect the current listener registry. |
setSimulate(bool): self / getSimulate(): bool |
Event · Events |
Toggle / inspect simulate mode. |
setDebugMode(bool): self / getDebugMode(): bool |
Event · Events |
Toggle / inspect debug mode. |
getDebug(): array / clearDebug(): self |
Event · Events |
Read / clear the debug log. |
getEmitter(): EventEmitter |
Event · Events |
Access the backing emitter. |
getInstance(): Event |
Events |
Return the shared dispatcher. |
setInstance(Event): void |
Events |
Inject a pre-configured dispatcher. |
reset(): void |
Events |
Drop the shared instance (tests, lifecycle resets). |
Full signatures and exception behaviour: docs/09-api-reference.md.
Migrating from initphp/event-emitter
The standalone initphp/event-emitter package has been merged into
this one and is now deprecated. If your code currently uses
\InitPHP\EventEmitter\EventEmitter, no source changes are
required — this package ships a backwards-compatibility alias:
- "initphp/event-emitter": "^1.0", + "initphp/events": "^2.0"
Composer will not install both packages side-by-side because
initphp/events:^2.0 declares a replace for initphp/event-emitter.
When you next touch the code, prefer the new canonical namespace:
// Before use InitPHP\EventEmitter\EventEmitter; // After use InitPHP\Events\EventEmitter;
The alias is intended as a transition aid and may be removed in a
future major release. One important behaviour change that comes
with v2.0: in 1.x, EventEmitter::emit() had a bug where the entire
listeners array was passed to call_user_func_array instead of each
individual listener, so emitted events silently fired no listeners at
all. That is fixed in 2.0 — if you had quietly broken emit() calls
in 1.x, they will now actually run their listeners.
See docs/07-migration-from-event-emitter.md for the full migration checklist.
Documentation
The full guide lives under docs/:
- Getting started
- The
Eventsfacade - Using
EventEmitterdirectly - Priorities and ordering
- Once-listeners, removal, and cleanup
- Debug and simulate modes
- Migrating from
initphp/event-emitter - Recipes (plugin systems, request lifecycle, WordPress-style hooks)
- API reference
Development
composer install composer test # PHPUnit
CI runs the test suite across PHP 7.3 – 8.4 and also lints the source
on PHP 5.6 / 7.0 / 7.1 / 7.2 so the php >= 5.6 library contract stays
honest.
Contributing & Security
Credits
License
Released under the MIT License.
initphp/events 适用场景与选型建议
initphp/events 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 125 次下载、GitHub Stars 达 6, 最近一次更新时间为 2022 年 03 月 17 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「event-dispatcher」 「events」 「observer」 「event-emitter」 「hooks」 「pubsub」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 initphp/events 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 initphp/events 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 initphp/events 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Interfaces, Traits and Nominal Classes used by Domain Entities Implementing Domain Events
Библиотека для реализаций паттерна Pub/Sub
A collection of observer classes that can be use in your Laravel application.
Domain Event Implementation for Symfony and Doctrine
Implementation of the transactional outbox pattern on top of rekalogika/domain-event
Wireless Cross-Component Communication
统计信息
- 总下载量: 125
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 6
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-03-17