定制 botta/cqbus 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

botta/cqbus

Composer 安装命令:

composer require botta/cqbus

包简介

Simple command/query bus for modern PHP applications

README 文档

README

CQBus

 

Simple PHP command/query bus

Packagist License: MIT CI Status

Installation

composer require botta/cqbus

Usage

Commands

use Botta\CQBus\CQBus;
use Botta\CQBus\Identity\Identity;
use Botta\CQBus\Requests\Command;
use Botta\CQBus\Requests\Handlers\RequestHandler;

final readonly class CreateFullName implements Command
{
    public function __construct(
        public string $firstName,
        public string $lastName,
    ) {
    }
}

final class CreateFullNameHandler implements RequestHandler
{
    public function execute(CreateFullName $request, Identity $identity): string
    {
        return $request->firstName . ' ' . $request->lastName;
    }
}

$cqBus = new CQBus();
$cqBus->registerHandler(CreateFullNameHandler::class);

$cqBus->execute(new CreateFullName('John', 'Doe')); // returns 'John Doe'

Queries

use Botta\CQBus\CQBus;
use Botta\CQBus\Identity\Identity;
use Botta\CQBus\Requests\Handlers\RequestHandler;
use Botta\CQBus\Requests\Query;

final class GetNews implements Query
{
}

final class GetNewsHandler implements RequestHandler
{
    public function execute(GetNews $request, Identity $identity): array
    {
        return ['news 1', 'news 2'];
    }
}

$cqBus = new CQBus();
$cqBus->registerHandler(GetNewsHandler::class);

$cqBus->execute(new GetNews()); // returns ['news 1', 'news 2']

Execution Identity

use Botta\CQBus\CQBus;
use Botta\CQBus\ExecutionContext;
use Botta\CQBus\Identity\Identity;
use Botta\CQBus\Requests\Command;
use Botta\CQBus\Requests\Handlers\RequestHandler;

final readonly class UserIdentity implements Identity
{
    public function __construct(private string $value)
    {
    }

    public function name(): string
    {
        return $this->value;
    }

    public function isAuthenticated(): bool
    {
        return true;
    }

    public function authenticationType(): ?string
    {
        return null;
    }

    public function roles(): array
    {
        return [];
    }

    public function properties(): array
    {
        return [];
    }
}

final class MyCommand implements Command
{
}

final class MyCommandHandler implements RequestHandler
{
    public function execute(MyCommand $request, Identity $identity): string
    {
        return $identity->name();
    }
}

$cqBus = new CQBus();
$cqBus->registerHandler(MyCommandHandler::class);

$cqBus->execute(new MyCommand(), ExecutionContext::empty()->withIdentity(new UserIdentity('Alice'))); // returns 'Alice'
$cqBus->execute(new MyCommand()); // returns 'Anonymous'

Context-aware handlers

use Botta\CQBus\CQBus;
use Botta\CQBus\ExecutionContext;
use Botta\CQBus\Requests\Command;
use Botta\CQBus\Requests\Handlers\ContextAwareRequestHandler;

final class MyCommand implements Command
{
}

final class MyCommandHandler implements ContextAwareRequestHandler
{
    public function execute(MyCommand $request, ExecutionContext $context): string
    {
        return $context->get('some-key');
    }
}

$cqBus = new CQBus();
$cqBus->registerContextAwareHandler(MyCommandHandler::class);

$cqBus->execute(new MyCommand(), ExecutionContext::empty()->with('some-key', 'some-value')); // returns 'some-value'

Middlewares

use Botta\CQBus\CQBus;
use Botta\\CQBus\\ExecutionContext;
use Botta\\CQBus\\Identity\\Identity;
use Botta\\CQBus\\Middleware;
use Botta\CQBus\Requests\Command;
use Botta\CQBus\Requests\Handlers\RequestHandler;
use Botta\CQBus\Requests\Request;

final class MyCommand implements Command
{
}

final class MyCommandHandler implements RequestHandler
{
    public function execute(MyCommand $request, Identity $identity): string
    {
        return 'handler';
    }
}

final class Log
{
    /** @var list<string> */
    public array $entries = [];
}

final class LoggingMiddleware implements Middleware
{
    public function __construct(private Log $log, private string $suffix = '')
    {
    }

    public function process(Request $request, callable $next, ExecutionContext $context): mixed
    {
        $this->log->entries[] = 'before' . $this->suffix;
        $result = $next($request);
        $this->log->entries[] = 'after' . $this->suffix;

        return $result;
    }
}

$log = new Log();
$cqBus = new CQBus();
$cqBus->registerHandler(MyCommandHandler::class);
$cqBus->registerMiddleware(new LoggingMiddleware($log, '1'));
$cqBus->registerMiddleware(new LoggingMiddleware($log, '2'));

$cqBus->execute(new MyCommand());

// $log->entries contains ['before2', 'before1', 'handler', 'after1', 'after2']

Middleware registration by priority

use Botta\CQBus\MiddlewarePriority;

$log = new Log();
$cqBus = new CQBus();
$cqBus->registerHandler(MyCommandHandler::class);
$cqBus->registerMiddleware(new LoggingMiddleware($log, 'Low'), MiddlewarePriority::Low);
$cqBus->registerMiddleware(new LoggingMiddleware($log, 'VeryHigh1'), MiddlewarePriority::VeryHigh);
$cqBus->registerMiddleware(new LoggingMiddleware($log, 'VeryHigh2'), MiddlewarePriority::VeryHigh);
$cqBus->registerMiddleware(new LoggingMiddleware($log, 'Normal'));

$cqBus->execute(new MyCommand());

// $log->entries contains:
//   'beforeVeryHigh2'
//   'beforeVeryHigh1'
//   'beforeNormal'
//   'beforeLow'
//   'handler'
//   'afterLow'
//   'afterNormal'
//   'afterVeryHigh1'
//   'afterVeryHigh2'

Handler instantiation

By default, CQBus resolves handlers and middleware classes with new $class().

$cqBus = new CQBus();

To integrate with a container, provide a resolver:

$cqBus = new CQBus(
    resolver: fn (string $class): object => $container->get($class),
);

You can also override instantiation for a specific handler:

$cqBus->registerHandler(
    CreateFullNameHandler::class,
    fn (): CreateFullNameHandler => new CreateFullNameHandler($repository),
);

The explicit factory takes precedence over the global resolver.

Internal requests

use Botta\CQBus\Requests\Command;
use Botta\CQBus\Requests\InternalRequest;

#[InternalRequest]
final class RebuildProjection implements Command
{
}
$cqBus = new CQBus(internalRequestsEnabled: true);

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-25

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固