Hook
The Hook package provides a small in-process event queue.
It lets code register named hooks, attach listeners to those hooks, and fire each hook later with one optional argument array.
In normal application code, the main entry points are Quantum\Hook\HookManager and the global hook() helper.
Package shape
The package contains four source pieces:
Quantum\Hook\HookManagerloads configured hook names, stores listeners, and fires hooksQuantum\Hook\Helpers\hook.phpexposes the sharedhook()helperQuantum\Hook\Exceptions\HookExceptiondefines package-specific runtime errorsQuantum\Hook\Enums\ExceptionMessagesstores local exception message templates
What the package actually does
HookManager creates a registry of hook names first, then allows listeners to be attached only to registered names.
When a hook is fired, the manager calls every queued listener for that hook and removes each listener from the store before invoking it. In practice, listeners are one-shot callbacks, not persistent subscriptions.
Startup behavior
The constructor ensures a hooks config entry exists:
- if
config()->has('hooks')is false, it importsconfig/hooks - it merges
HookManager::CORE_HOOKSwithconfig()->get('hooks') ?: [] - it registers each resulting hook name into the internal store
CORE_HOOKS is currently an empty array, so out of the box the package depends on the configured hook list.
Use a flat list of hook names in config/hooks, for example:
return [
'user.registered',
'mail.sent',
'report.generated',
];
If the list contains duplicate names, manager construction fails before you can attach or fire listeners.
Important constraints
- hook names must be registered before
on()orfire()can use them config/hooksshould return a plain list of hook names, not a nested structure- duplicate hook names fail during registration, including duplicates loaded from configuration
- unregistered hook names fail both when attaching listeners and when firing
- firing a registered hook with no queued listeners is a no-op
- listeners are consumed on first
fire()call fire()always passes exactly one argument to each listener: the?array $argsvalue- a newly registered hook starts with an empty listener queue
What the package does not do
The package is intentionally narrow.
It does not:
- provide listener priorities
- keep listeners after they are fired
- return values from listeners
- aggregate listener results
- expose a public API for registering new hook names after construction
- include wildcard hooks or pattern matching