Skip to main content

CQRS Example

Implementing CQRS in a PHP Project

// Command Interface
interface Command {}

// Command Handler Interface
interface CommandHandler {
public function handle(Command $command): void;
}

// Example Command
class CreateUserCommand implements Command {
public $userId;
public $name;
public $email;

public function __construct($userId, $name, $email) {
$this->userId = $userId;
$this->name = $name;
$this->email = $email;
}
}

// Example Command Handler
class CreateUserCommandHandler implements CommandHandler {
private $userRepository;

public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}

public function handle(Command $command): void {
$user = new User($command->userId, $command->name, $command->email);
$this->userRepository->save($user);

// Publish event to update read model
EventDispatcher::dispatch(new UserCreatedEvent($command->userId, $command->name, $command->email));
}
}

// Query Interface
interface Query {}

// Query Handler Interface
interface QueryHandler {
public function handle(Query $query);
}

// Example Query
class GetUserByIdQuery implements Query {
public $userId;

public function __construct($userId) {
$this->userId = $userId;
}
}

// Example Query Handler
class GetUserByIdQueryHandler implements QueryHandler {
private $readRepository;

public function __construct(ReadRepository $readRepository) {
$this->readRepository = $readRepository;
}

public function handle(Query $query) {
return $this->readRepository->findById($query->userId);
}
}

// Event
class UserCreatedEvent {
public $userId;
public $name;
public $email;

public function __construct($userId, $name, $email) {
$this->userId = $userId;
$this->name = $name;
$this->email = $email;
}
}

// Event Dispatcher (Simple Implementation)
class EventDispatcher {
private static $listeners = [];

public static function addListener($eventClass, callable $listener) {
self::$listeners[$eventClass][] = $listener;
}

public static function dispatch($event) {
$eventClass = get_class($event);
if (isset(self::$listeners[$eventClass])) {
foreach (self::$listeners[$eventClass] as $listener) {
$listener($event);
}
}
}
}

// Listener to Update Read Model
EventDispatcher::addListener(UserCreatedEvent::class, function(UserCreatedEvent $event) {
// Update read model with new user data
$readRepository = new ReadRepository();
$readRepository->add($event->userId, $event->name, $event->email);
});