rasuvaeff / yii3-outbox-db
Database-backed outbox storage for Yii3
Requires
- php: 8.3 - 8.5
- rasuvaeff/yii3-outbox: ^1.0
- yiisoft/db: ^2.0
- yiisoft/db-migration: ^2.0
Requires (Dev)
- ergebnis/composer-normalize: ^2.51
- friendsofphp/php-cs-fixer: ^3.95
- infection/infection: ^0.33
- maglnet/composer-require-checker: ^4.17
- rector/rector: ^2.4
- roave/backward-compatibility-check: ^8.0
- testo/bridge-infection: ^0.1.6
- testo/testo: ^0.10.25
- vimeo/psalm: ^6.16
- yiisoft/cache: ^3.2
- yiisoft/db-sqlite: ^2.0
- yiisoft/injector: ^1.2
- yiisoft/test-support: ^3.0
This package is auto-updated.
Last update: 2026-07-25 13:27:12 UTC
README
Database-backed storage for rasuvaeff/yii3-outbox.
Durably persists outbox messages in a yiisoft/db table so a worker can publish
or export them asynchronously — surviving process restarts and downstream outages.
Using an AI coding assistant? llms.txt has a compact API reference you can use.
Requirements
- PHP 8.3+
rasuvaeff/yii3-outbox^1.0yiisoft/db^2.0,yiisoft/db-migration^2.0
Installation
composer require rasuvaeff/yii3-outbox-db
Usage
Migration
Register the bundled migration by namespace — no vendor paths:
// config/common/di/migration.php use Yiisoft\Db\Migration\Service\MigrationService; return [ MigrationService::class => [ 'setSourceNamespaces()' => [[ 'App\\Migration', 'Rasuvaeff\\Yii3OutboxDb\\Migration', ]], ], ];
./yii migrate:up
Set the table name in params — the same value reaches the migration and
DbOutboxStorage:
// config/common/params.php 'rasuvaeff/yii3-outbox-db' => [ 'table' => 'my_outbox', 'table_prefix' => '', // prepended to `table`; e.g. 'rsv_' → rsv_my_outbox ],
Index names follow the table name (idx_my_outbox_pending), so two
installations can share one PostgreSQL schema — index names are unique per
schema there, not per table.
Do not configure the migration through the DI container.
M...::class => ['__construct()' => ['table' => ...]]does not work: the migration is built byInjector::make(), which resolves arguments by type and never reads a container definition keyed by the migration's own class. Worse, adding that definition makes the container fatal at build time in every request, because the class is not autoloadable until the migration runner requires it. That recipe was documented in 1.x; it never worked.
Recording and processing
use Rasuvaeff\Yii3Outbox\Outbox; use Rasuvaeff\Yii3OutboxDb\DbOutboxStorage; $storage = new DbOutboxStorage(db: $connection); // ConnectionInterface $outbox = new Outbox(storage: $storage, clock: $clock); // request path — durable, no network call to the sink $outbox->record(type: 'ab.exposure', payload: '{"experiment":"checkout"}'); // worker — fetch a batch of one consumer's types and process them $pending = $storage->findPending(types: ['ab.exposure', 'ab.conversion'], limit: 1000);
Storage API
| Method | Purpose |
|---|---|
save(OutboxMessage) |
upsert by id (initial record or retry re-save) |
findPending(array $types = [], int $limit = 1000) |
pending rows, optional type filter, created_at ASC |
markPublished(OutboxMessage) |
re-save with Published status |
markFailed(OutboxMessage) |
re-save with Failed status |
getById(string $id) |
single message or null |
deleteByStatus(OutboxStatus) |
housekeeping (e.g. purge Published) |
findPending's $types filter lets several consumers — a generic Processor
and a specialized exporter — share one outbox without competing for each other's
messages.
Yii3 DI
The config-plugin binds StorageInterface to DbOutboxStorage from
config/di.php. Core yii3-outbox binds nothing, so this backend (or the
application) is the single source of StorageInterface. Set the table name in
params:
// config/params.php 'rasuvaeff/yii3-outbox-db' => ['table' => 'outbox'],
Security
- All values are written through
yiisoft/dbparameterized commands. OutboxRowMappervalidates every column and rejects corrupt rows withInvalidOutboxRowException— no silent coercion.- Payloads may contain PII; retention/purging is the application's responsibility
(
deleteByStatushelps).
Examples
Runnable scripts live in examples/.
Development
make build # full gate: validate + normalize + require-checker + cs + psalm + test make cs-fix make psalm make test make test-coverage make mutation
Core yii3-outbox is consumed via a path repository while unpublished — see
AGENTS.md for the monorepo-root Docker invocation.
License
BSD-3-Clause. See LICENSE.md.