Sébastien TIMONER
Expert en développement web et gestion d'équipes techniques, je me spécialise dans la création et l'optimisation de solutions numériques performantes. Grâce à une maîtrise approfondie de technologies modernes comme React.js, Node.js, TypeScript, Symfony, Docker et FrankenPHP, j'assure la réussite de projets SaaS complexes, de la conception à la mise en production, pour des entreprises de divers secteurs.
Tu entends parler de CQRS partout mais tu te demandes comment l'appliquer sans dégainer Symfony ou Laravel ? Bonne nouvelle : on peut explorer la Command Query Responsibility Segregation en PHP vanille avec juste une organisation claire et quelques classes bien pensées. Prends ton éditeur, on pose les bases ensemble.
Si tu dois rester sur une version antérieure, assure-toi que les features utilisées (constructeurs promotionnés, propriétés , etc.) sont disponibles ou adapte les snippets.
CQRS consiste à séparer la lecture (Query) de l'écriture (Command). On obtient deux chemins optimisés :
Cette séparation découle naturellement de la philosophie DDD, mais tu peux l'adopter sans tout le formalisme. Les gains immédiats :
Rappelle-toi toutefois que CQRS ajoute un peu de complexité structurelle. Sur un CRUD basique, c'est peut-être trop lourd. Utilise-le quand les règles métiers ou les besoins de scalabilité le justifient.
On peut rester léger avec une arborescence simple :
On distingue Domain (règles métier), Application (cas d’usage) et Infrastructure (implémentations concrètes).
Créons un agrégat et son repository :
La commande transporte l'intention. Le handler orchestre la logique métier.
Remarque importante : le handler ne retourne rien. Si tu veux relire l’article, tu passeras par une Query.
On expose ici un tableau prêt à être sérialisé, sans dépendre du modèle domaine dans la couche présentation.
Tu pourras remplacer cette implémentation par une version Doctrine, PDO ou API externe plus tard, sans toucher aux handlers.
Le pattern CQRS devient agréable quand tu centralises la résolution des handlers :
php
php
Ces bus restent naïfs mais suffisent pour comprendre la mécanique. Dans un vrai projet, tu pourrais les brancher sur un conteneur d’injection de dépendances (PHP-DI, Symfony DI, etc.).
public/index.php
php
L’opérateur (...)
(first-class callable) disponible depuis PHP 8.1 est pleinement pris en charge par PHP 8.4. Si tu dois supporter une version antérieure (8.0 ou moins), remplace-le par fn ($command) => $createHandler($command)
.
Une fois cette base en place, tu peux enrichir ta solution :
ArticlePublished
quand la commande réussit, puis consomme-le dans une autre couche.Avec ce squelette, tu peux introduire CQRS progressivement dans un projet existant ou démarrer un nouveau service sans framework. La clé reste de garder la frontière lecture/écriture claire et de faire évoluer ton architecture par itérations. Bonne expérimentation !
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