Lifecycle Management
PHP Event Sourcing Projection Lifecycle and CLI
The Problem
Your projection's table schema changed, or you found a bug in a handler and the read model has wrong data. How do you set up, tear down, and rebuild projections without writing manual SQL scripts?
Ecotone provides lifecycle hooks — methods on your projection class that are called at specific moments — and CLI commands to trigger them.
Lifecycle Hooks
Initialization
Called when the projection is first set up. Use it to create tables, indexes, or any storage structure:
#[ProjectionInitialization]
public function init(): void
{
$this->connection->executeStatement(<<<SQL
CREATE TABLE IF NOT EXISTS ticket_list (
ticket_id VARCHAR(36) PRIMARY KEY,
ticket_type VARCHAR(25),
status VARCHAR(25)
)
SQL);
}Delete
Called when the projection is permanently removed. Clean up all storage:
Reset
Called when the projection needs to be rebuilt from scratch. Clear the data but keep the structure:
After a reset, the projection's position is set back to the beginning. The next trigger will replay all events from the start.
Flush
Called after each batch of events is processed. Useful for flushing buffers or intermediate state:
See Execution Modes for how batching and flushing work together.
CLI Commands
Initialize a Projection
Delete a Projection
Calls #[ProjectionDelete] and removes all tracking state:
Backfill a Projection
Populates a fresh projection with historical events. See Backfill and Rebuild for details:
Rebuild a Projection (Enterprise)
Resets the projection and replays all events. See Backfill and Rebuild for details:
Automatic vs Manual Initialization
By default, projections auto-initialize the first time an event triggers them. This means you don't need to run any CLI command — the #[ProjectionInitialization] method is called automatically.
If you need manual control (for example, during blue-green deployments), you can disable auto-initialization:
Reset and Trigger
To rebuild a projection manually, you can reset it (clears data and position) and then trigger it (starts processing from the beginning):
Reset — calls
#[ProjectionReset], clears position to the beginningTrigger — starts processing events from position 0, rebuilding the entire Read Model
This is useful when you've fixed a bug in a handler and need to reprocess all events to correct the data.
Last updated
Was this helpful?