quantum-php / quantum-php/framework
Enhance Hook package and boot pipeline to support bootstrap-time stage lifecycle events for optional integrations
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 36
- Forks
- 22
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Enhance the current Hook package and boot pipeline so optional integrations can subscribe to stage lifecycle events during bootstrap.
The goal is to support stage-owned BEFORE / AFTER hook points, allowing optional integrations such as debugbar to initialize at precise boot boundaries without being hardcoded into the core pipeline.
Why
The current Hook package is close to usable for this direction, but it still needs framework-level support for bootstrap-time stage events.
Current needs:
- optional integrations should be able to initialize during boot without hardcoded stages in core
- boot lifecycle points should be attached to meaningful stage boundaries
- the framework should not need special-purpose stages such as
InitDebuggerStagefor optional tooling - the current Hook mechanism should be strengthened rather than replaced
A better model is:
- each boot stage can define
BEFOREandAFTERhook names BootPipelinedispatches those hook points automatically around stage execution- optional integrations subscribe to the stage boundary they care about
For example, debugbar should be able to initialize at:
LoadModulesStage::BEFORE
instead of requiring a dedicated hardcoded debugger stage in core.
Goals
- keep the current Hook-style mechanism and evolve it
- make hook registration available during bootstrap
- allow boot stages to define
BEFORE/AFTERhook names - make
BootPipelinedispatch those hook points automatically - support optional integrations without hardcoded core dependencies
- keep the mechanism usable for user-defined application and module events, not only framework lifecycle hooks
Proposed Changes
- enhance the Hook package so listener registration is safe early in bootstrap
- introduce clearer API naming:
listen()instead ofon()dispatch()instead offire()
- keep
on()/fire()as compatibility aliases if needed - avoid positional payload arrays for framework-defined hook payloads and use stable named payloads
- allow boot stages to define lifecycle hook names such as
BEFOREandAFTER - update
BootPipelineto dispatch those hooks automatically around stage execution when present
Architectural Constraint
The mechanism introduced here must remain extensible for future event sources beyond boot stages, including:
- route-level events
- request/response events
- console lifecycle events
- user-defined business/domain events
Stage lifecycle hooks are the first concrete use case for this mechanism, but they must not lock the design into a stage-only event model.
Example Direction
Stage definition:
final class LoadModulesStage implements BootStageInterface
{
public const BEFORE = 'boot.modules.before';
public const AFTER = 'boot.modules.after';
public function process(AppContext $context): void
{
// existing stage logic
}
}
Pipeline behavior:
foreach ($this->stages as $stage) {
if (defined(get_class($stage) . '::BEFORE')) {
event()->dispatch($stage::BEFORE, [
'context' => $context,
]);
}
$stage->process($context);
if (defined(get_class($stage) . '::AFTER')) {
event()->dispatch($stage::AFTER, [
'context' => $context,
]);
}
}
Optional integration subscription:
event()->listen(LoadModulesStage::BEFORE, function (array $payload): void {
$context = $payload['context'];
debugbar()->boot($context);
});
Acceptance Criteria
- hook/event listener registration is safe during bootstrap
- boot stages can define
BEFORE/AFTERlifecycle hook names BootPipelinedispatches those lifecycle hooks automatically when defined- framework-defined hook payloads use stable named payloads rather than positional arrays
- clearer method names such as
listen()anddispatch()are introduced - existing
on()/fire()usage remains compatible if aliasing is chosen - optional integrations can subscribe to boot stage boundaries without hardcoded core stages
- the design remains extensible for non-stage framework events and user-defined business events
- tests cover bootstrap-time registration and stage lifecycle hook dispatch
- docs are updated as needed
Notes
Relevant code:
src/Hook/HookManager.phpsrc/Hook/Helpers/hook.phpsrc/App/BootPipeline.phpsrc/App/Stages/InitHttpStage.phpsrc/App/Stages/LoadModulesStage.phptests/Unit/Hook/HookManagerTest.phptests/Unit/Hook/Helpers/HookHelperTest.php
This ticket should be treated as the foundation for:
- lifecycle hooks
- debugbar via lifecycle hooks
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/Hook/HookManager.php, src/Hook/Helpers/hook.php, and their unit tests to understand the current registration and dispatch behavior. Then inspect src/App/BootPipeline.php and the listed stages to trace bootstrap execution. Done means bootstrap-time listeners and stage BEFORE/AFTER hooks work with stable named payloads, compatibility is preserved as needed, and the relevant tests and documentation are updated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100