mrhdolek / slim4-boirlerplate
使用 AMQP、DDD 和 Doctrine 的 Slim 4 框架骨架
Requires
- php: ^8.2
- ext-json: *
- ext-pcntl: *
- ext-sockets: *
- awurth/slim-validation: ^5.0
- doctrine/data-fixtures: ^1.6
- doctrine/migrations: ^3.6
- doctrine/orm: ^2.15
- fakerphp/faker: ^1.23
- laminas/laminas-diactoros: ^3.3
- lcobucci/clock: ^3.1
- monolog/monolog: ^2.8
- peppeocchi/php-cron-scheduler: ^4.0
- php-amqplib/php-amqplib: ^3.2
- php-di/php-di: ^7.0
- php-di/slim-bridge: ^3.4
- predis/predis: ^2.2
- ramsey/uuid: ^4.7
- slim/psr7: ^1.5
- slim/slim: ^4.10
- slim/twig-view: ^3.3
- swoole/ide-helper: ^5.1
- symfony/cache: ^6.3
- symfony/console: ^6.3
- symfony/doctrine-bridge: ^6.3
- symfony/finder: ^6.3
- symfony/yaml: ^6.2
- thecodingmachine/safe: ^2.5
- vlucas/phpdotenv: ^5.5
- zircote/swagger-php: ^4.7
Requires (Dev)
- blumilksoftware/codestyle: *
- jangregor/phpstan-prophecy: ^1.0.0
- league/openapi-psr7-validator: ^0.22.0
- phpspec/prophecy-phpunit: ^2.0
- phpstan/extension-installer: ^1.2.0
- phpstan/phpstan: ^1.8
- phpunit/phpunit: ^9.5.26
- qossmic/deptrac-shim: ^1.0
- spatie/phpunit-snapshot-assertions: ^4.2
This package is auto-updated.
Last update: 2024-09-18 13:40:14 UTC
README
使用 AMQP 和 DDD 的 Slim 4 框架骨架
我受到 robiningelbrecht 的启发,创建了此骨架。
项目设置
开发
如果权限有问题,请在 make example 前添加 sudo
sudo make install
sudo make start
运行 env for Mac/Linux
make install
make start
make db-create
运行 env for Windows
请安装 Windows 的 packages makefile http://gnuwin32.sourceforge.net/packages/make.htm
make install
make start
make db-create
环境可用的地址
https://
Rest Api 文档
https:///docs/v1
RabbitMq 控制台
https://:15672
所有命令
make help
一些示例
注册新路由
namespace App\Application\Actions\User; class GetAllUsersAction extends UserAction { public function __construct( private readonly UserService $userService, protected LoggerInterface $logger, ) { parent::__construct($logger); } protected function action(): Response { $user = $this->userService->getAllUsers(); return $this->respondWithJson(new UsersResponseDto($user)); } }
转到 config/routes.php
并为您的 RequestHandler 添加路由
return function (App $app) { $group->get("/users", GetAllUsersAction::class) ->setName("getAllUsers"); };
控制台命令
控制台应用程序使用 Symfony 控制台组件来利用 CLI 功能。
#[AsCommand(name: 'app:user:create')] class CreateUserConsoleCommand extends Command { protected function execute(InputInterface $input, OutputInterface $output): int { // ... return Command::SUCCESS; } }
调度命令
要调度一个命令,我们使用 GO\Scheduler 类。此类允许我们定义命令执行的时间和频率。以下是一个每天运行命令的示例
$scheduler = new GO\Scheduler(); $scheduler->php('/path/to/command app:user:create')->daily(); $scheduler->run();
在此示例中,app:user:create 命令被安排每天运行。
运行调度器
调度器应该由系统 cron 作业触发,以确保定期运行。通常,您会设置一个 cron 作业来执行初始化和运行调度器的 PHP 脚本。
例如,每分钟运行一次的 cron 作业可能看起来像这样
* * * * * ./bin/console.php schedule
此设置确保您的计划命令可靠且按时执行。
领域事件和事件处理器
框架实现了 amqp 协议,并带有处理程序,允许轻松将事件推送到队列。每个事件都必须实现一个处理程序,以消费事件。
创建新事件
class UserWasCreated extends DomainEvent { }
创建对应的事件处理程序
namespace App\Domain\Entity\User\DomainEvents; #[AsEventHandler] class UserWasCreatedEventHandler implements EventHandler { public function __construct( ) { } public function handle(DomainEvent $event): void { assert($event instanceof UserWasCreated); // Do stuff. } }
事件
创建新事件
class UserWasCreated extends DomainEvent { public function __construct( private UserId $userId, ) { } public function getUserId(): UserId { return $this->userId; } }
使用 RabbitMQ 异步处理命令
此项目的 AMQP 实现是 RabbitMQ,但它可以轻松切换到例如 Amazon 的 AMQP 解决方案。
注册新队列
#[AsAmqpQueue(name: "user-command-queue", numberOfWorkers: 1)] class UserEventQueue extends EventQueue { }
排队事件
final readonly class UserEventsService { public function __construct( private UserEventQueue $userEventQueue, ) {} public function userWasCreated(User $user): void { $this->userEventQueue->queue(new UserWasCreated($user)); } }
消费您的队列
> docker-compose run --rm php bin/console.php app:amqp:consume user-command-queue
创建新实体
如果您已创建新实体并想将其映射到数据库,必须在 src/Infrastructure/Persistence/Doctrine/Mapping 中创建一个 xml。它必须命名,以便确切地表示要映射的实体位置。
接口/全局对象注册表的绑定
要注册依赖关系或创建单个配置的全局实例,您需要转到 config/container.php
将数据库数据映射到自定义对象
要将数据库中的数据映射到自定义对象,您需要扩展 Doctrine/DBAL/Types。
use App\Domain\ValueObject\UserType; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\StringType; class UserTypeType extends StringType { const TYPE_NAME = 'UserType'; public function convertToPHPValue($value, AbstractPlatform $platform): ?UserType { return null !== $value ? UserType::fromString($value) : null; } public function getName() { return self::TYPE_NAME; } }
扩展后,您需要在 xml 中添加注释,说明您正在将字段映射到对象。
<field name="type" type="UserType" column="type" nullable="true"/>
最后,您必须将新类型添加到配置 doctrine 的 config/container.php 中
use Doctrine\DBAL\Connection; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\Types\Type; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Tools\Setup; return [ ... EntityManager::class => function (Settings $settings): EntityManager { $config = Setup::createXMLMetadataConfiguration( $settings->get("doctrine.metadata_dirs"), $settings->get("doctrine.dev_mode"), ); if (!Type::hasType('UserType')) { Type::addType('UserType', UserTypeType::class); } return EntityManager::create($settings->get("doctrine.connection"), $config); }, ... ];
数据库迁移
为了管理数据库迁移,使用 doctrine/migrations 包。
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="App\Domain\Entity\User\User" table="users"> <id name="id" type="integer" column="id"> <generator strategy="SEQUENCE"/> <sequence-generator sequence-name="user_id_seq" allocation-size="1" initial-value="1"/> </id> <field name="username" type="string" column="name" length="64" nullable="true"/> <field name="firstName" type="string" column="surname" length="64" nullable="true"/> <field name="lastName" type="string" column="email" length="64" nullable="true"/> <options> <option name="collate">utf8mb4_polish_ci</option> </options> </entity> </doctrine-mapping>
映射是通过一个 yaml 实现的,它将你的实体从域映射到数据库中的结构。如果你在 yaml 中更改了某些内容,可以使用以下命令根据差异生成迁移。
> docker-compose run --rm php vendor/bin/doctrine-migrations diff > docker-compose run --rm php vendor/bin/doctrine-migrations migrate
Swoole
要使用 swoole,只需在 .env 中设置 DOCKER_TARGET_APP=swoole
并重新构建应用程序容器。
文档
了解更多信息,请查看以下链接