Sébastien TIMONER
作为 Web 开发和技术团队管理专家,我专注于创建和优化高性能数字解决方案。通过对 React.js、Node.js、TypeScript、Symfony、Docker 和 FrankenPHP 等现代技术的深入掌握,我确保为各行业企业的复杂 SaaS 项目从设计到生产的成功。
到处都有人谈论 CQRS,但你可能仍然好奇:不动用 Symfony 或 Laravel 这样的框架,该怎么实践?好消息是,我们可以在纯 PHP 环境下体验 Command Query Responsibility Segregation。只需要清晰的结构和几段精心设计的类。打开编辑器,一起来搭好基础。
如果必须停留在更低版本,请确认这里用到的特性(构造函数提升、 属性等)是否可用,或按需调整示例代码。
CQRS 的核心是将读取(Query)与写入(Command)分离,从而形成两条优化路径:
这种分离源自 DDD 的理念,但完全可以在不引入繁琐形式的情况下采用。立竿见影的好处包括:
需要注意,CQRS 会带来一定的结构复杂度。对于简单的 CRUD,可能会显得过度设计。请在业务规则或扩展需求值得的情况下再采用。
下面的简单目录结构就能满足需求:
这能清晰地划分 Domain(业务规则)、Application(用例)以及 Infrastructure(具体实现)。
我们创建一个 聚合及其仓储:
命令承载意图,处理器协调业务逻辑。
重点:处理器不会返回任何内容。如需再次读取文章,需要通过 Query。
这里返回的是可以直接序列化的数组,避免展示层与领域模型耦合。
后续可以替换为 Doctrine、PDO 或外部 API,实现不会影响处理器。
当你把处理器解析集中管理后,CQRS 的优势会更明显:
这些总线虽然朴素,但足以理解其机制。真实项目中,你可以把它们接入依赖注入容器(PHP-DI、Symfony DI 等)。
运算符(first-class callable)自 PHP 8.1 起可用,PHP 8.4 中完全支持。若要兼容 8.0 及以下版本,可替换为 。
打好基础后,可以逐步增强方案:
借助这个骨架,你可以在现有项目中循序渐进地引入 CQRS,也能在无框架的情况下启动新服务。关键是保持读写边界清晰,让架构逐步迭代演进。祝你玩得开心!
php -v
readonly
php -S 127.0.0.1:8000 -t public
readonly
src/
Domain/
Article.php
ArticleRepository.php
Application/
Command/
CreateArticle/
CreateArticleCommand.php
CreateArticleHandler.php
Query/
ListArticles/
ListArticlesQuery.php
ListArticlesHandler.php
Bus/
CommandBus.php
QueryBus.php
Infrastructure/
InMemoryArticleRepository.php
public/
index.php
Article
php
php
php
php
php
php
php
php
php
public/index.php
php
(...)
fn ($command) => $createHandler($command)
ArticlePublished