cubadevops / flexi
尊重标准的灵活框架
Requires
- php: >=7.4
- ext-json: *
- cubadevops/upgrader: ^1.6
- guzzlehttp/guzzle: ^7.7
- psr/cache: ^1.0
- psr/container: ^2.0
- psr/event-dispatcher: ^1.0
- psr/http-client: ^1.0
- psr/http-factory: ^1.0
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/link: ^1.0
- psr/log: ^1.1
- psr/simple-cache: ^1.0
- symfony/error-handler: ^5.4
- vlucas/phpdotenv: ^5.5
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.57
- phpunit/phpunit: ^9.6
- roave/security-advisories: dev-latest
- vimeo/psalm: ^5.22.2
This package is auto-updated.
Last update: 2024-10-01 16:10:54 UTC
README
Flexi是一个模块化的PHP框架,旨在简化可扩展和可维护应用程序的开发。它利用依赖注入(DI)、灵活的路由系统、CQRS和事件驱动架构。
目录
特性
- 模块化与可扩展性:Flexi提供了一种模块化架构,促进代码组织和复用。其可扩展性允许开发者根据特定项目需求自定义和扩展功能。
- 依赖注入:内置对依赖注入的支持简化了依赖项的管理和注入,增强了代码的可维护性和可测试性。Flexi中的DI使用容器以懒加载实例化方式管理服务。
- 灵活路由:灵活的路由系统使得开发者可以轻松定义和管理HTTP请求处理,简化了复杂路由逻辑的开发,并支持中间件。
- 事件驱动架构:Flexi的事件驱动架构允许事件监听器异步处理事件,促进应用程序设计中的松耦合和灵活性。
- CQRS与可扩展性:支持命令查询责任分离(CQRS)促进了可扩展性和性能优化。结合异步处理等功能,Flexi简化了可扩展应用程序的开发,使其能够处理高流量和数据负载。
- 通过JSON配置:Flexi中的配置通过JSON文件管理,便于定义服务、路由、事件、查询和命令。这种方法简化了配置管理,并促进了项目间的统一性。将实现Json Schema来验证配置文件。
结构
- 核心:
src/
目录包含构成框架的核心类和接口。 - 模块:
modules/
目录包含不属于核心框架的所有代码。每个模块是一个独立的目录,包含自己的控制器、服务和配置文件。可以添加到应用程序中的即插即用插件可以扩展其功能。 - 配置:
src/Config/
和modules/*/Config
目录包含框架的配置文件(路由
、命令
、查询
、事件监听器
和服务
)。 - 控制台:
bin/
目录包含可以从命令行运行的控制台应用程序。(即将推出)
安装
您可以使用Composer安装Flexi框架
composer create-project cubadevops/flexi my-app
此命令在my-app
目录中创建了一个最小化的启动模板应用程序。
安装后的步骤
要开始使用Flexi框架,请确保您
- 配置您的Web服务器,使其指向项目根目录中的
public
目录。 - 拒绝直接访问除
public
目录之外的所有目录。 - 直接服务静态文件,并将所有其他请求路由到
public
目录中的index.php
文件。 - 设置
.env
文件,包含您的应用程序所需的环境变量。
配置完成后,浏览到您应用程序的URL以查看欢迎页面。如果您使用Docker的默认配置,您可以通过https://:8080访问应用程序。
配置
Flexi的配置通过JSON文件进行管理。这些文件定义了应用程序中使用的服务、路由、事件、查询和命令。
服务
服务在位于Config
目录中的services.json
文件中定义。该文件概述了每个服务应如何实例化,是直接实例化还是通过工厂方法。
示例
{ "services": [ { "name": "CubaDevOps\\Flexi\\Infrastructure\\Classes\\Configuration", "factory": { "class": "CubaDevOps\\Flexi\\Infrastructure\\Factories\\ConfigurationFactory", "method": "getInstance", "arguments": [] } }, { "name": "session", "alias": "CubaDevOps\\Flexi\\Domain\\Classes\\NativeSessionStorage" }, { "name": "logger", "class": { "name": "CubaDevOps\\Flexi\\Infrastructure\\Classes\\PsrLogger", "arguments": [ "@CubaDevOps\\Flexi\\Domain\\Classes\\InFileLogRepository" ] } }, { "glob": "/modules/*/Config/services.json" } ] }
注意
- 使用
alias
键可以以不同的名称引用服务。 - 以
@
为前缀的参数是其他服务的引用(也可以是别名) - 以
ENV.
为前缀的参数是环境变量的引用。 - 没有
@
或ENV.
前缀的引号字符串被视为字符串值。 - 所有其他值都视为标准的json_decode值。
- 使用
glob
键可以从modules
中包含服务。
路由
路由在routes.json
文件中定义。每个路由指定HTTP方法、路径以及应处理请求的控制器。
示例
{ "routes": [ { "name": "health", "path": "/health", "method": "GET", "controller": "CubaDevOps\\Flexi\\Infrastructure\\Controllers\\HealthController", "parameters": [], "middlewares": [ "CubaDevOps\\Flexi\\Infrastructure\\Middlewares\\AuthCheckMiddleware" ] }, { "name": "404", "path": "/not-found", "method": "GET", "controller": "CubaDevOps\\Flexi\\Infrastructure\\Controllers\\NotFoundController" }, { "glob": "/modules/*/Config/routes.json" } ] }
注意
- 如果您想附加中间件,则控制器应实现
Psr\Http\Server\RequestHandlerInterface
接口。然而,它们必须有一个handle
方法,该方法接收一个Psr\Http\Message\ServerRequestInterface
并返回一个Psr\Http\Message\ResponseInterface
。 - 可选的
parameters
键用于定义应传递给请求的参数数量以及它们是否必需。 - 可选的
middlewares
键用于定义在控制器之前应执行的中间件。它们按定义的顺序执行,如果它们直接返回响应或传递请求到下一个中间件,则可以停止执行链。 - 使用
glob
键可以从modules
中包含额外的路由定义。
事件和监听器
事件和监听器在listeners.json
文件中定义。该文件将事件映射到相应的监听器。
示例
[ { "event": "*", "listeners": [ "CubaDevOps\\Flexi\\Application\\EventListeners\\LoggerEventListener" ] }, { "glob": "/modules/*/Config/listeners.json" } ]
注意
event
键可以是特定的事件名称或通配符*
以监听所有事件。- 监听器类应实现
CubaDevOps\Flexi\Domain\Interfaces\EventListenerInterface
接口。
查询
查询在queries.json
文件中定义。每个查询处理程序映射到特定的DTO和可选的CLI别名。
示例
{ "handlers": [ { "id": "CubaDevOps\\Flexi\\Domain\\DTO\\EmptyVersionDTO", "cli_alias": "version", "handler": "CubaDevOps\\Flexi\\Application\\UseCase\\Health" }, { "glob": "/modules/*/Config/queries.json" } ] }
注意
- 处理程序应实现
CubaDevOps\Flexi\Domain\Interfaces\HandlerInterface
接口。
命令
命令在commands.json
文件中以与查询类似的方式定义。
示例
{ "handlers": [ { "glob": "/modules/*/Config/commands.json" } ] }
注意
- 处理程序应实现
CubaDevOps\Flexi\Domain\Interfaces\HandlerInterface
接口。
使用
路由器
Router
类负责管理路由并将请求分配给适当的控制器。
示例用法
use CubaDevOps\Flexi\Domain\Classes\Router; use Psr\Http\Message\ServerRequestInterface; use CubaDevOps\Flexi\Domain\Factories\ContainerFactory; /** @var Router $router */ $router = ContainerFactory::getInstance()->get(Router::class); // or use router alias $route = $router->getByName('home'); // Get a route by name $route->getPath(); // Get the path of the route to pass to the template
事件系统
Flexi的事件系统基于EventBus模式。事件被分发到监听器,它们可以相应地处理它们。
示例
use CubaDevOps\Flexi\Domain\Interfaces\EventBusInterface; use CubaDevOps\Flexi\Domain\Classes\Event; use CubaDevOps\Flexi\Application\UseCase\Health; use CubaDevOps\Flexi\Domain\Factories\ContainerFactory; use CubaDevOps\Flexi\Domain\Classes\EventBus; $eventBus = ContainerFactory::getInstance()->get(EventBus::class); $event = new Event('health-check', Health::class, ['from' => $_SERVER['REMOTE_ADDR']); $eventBus->notify($event);
CQRS
Flexi实现了CQRS模式,对命令和查询有单独的处理。
命令示例
use CubaDevOps\Flexi\Domain\Classes\CommandBus; // Assume $command is a class that implements the DTOInterface $commandBus->execute($command);
查询示例
use CubaDevOps\Flexi\Domain\Classes\QueryBus; // Assume $query is a class that implements the DTOInterface $result = $queryBus->execute($query);
控制器和响应
响应是PSR-7响应对象,可以从控制器或中间件返回。扩展了CubaDevOps\Flexi\Infrastructure\Classes\HttpHandler
的控制器可以使用createResponse
方法轻松构建响应。如果您没有扩展HttpHandler
,则可以使用实现Psr\Http\Message\ResponseFactoryInterface
接口的工厂来构建响应。Flexi使用GuzzleHttp\Psr7\HttpFactory
作为默认工厂。
示例
namespace CubaDevOps\Flexi\Modules\Home\Infrastructure\Controllers; use CubaDevOps\Flexi\Infrastructure\Classes\HttpHandler; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; class AuthenticatedController extends HttpHandler { public function handle(ServerRequestInterface $request): ResponseInterface { if (!$this->queue->isEmpty()) { // This block allows to execute middlewares return $this->getNextMiddleware()->process($request, $this); } $response = $this->createResponse(); $response->getBody()->write('Authorized'); return $response; } }
中间件
中间件是可以在控制器之前执行的类。它们可以修改请求、响应或停止执行链。中间件应实现Psr\Http\Server\MiddlewareInterface
接口。
示例
namespace CubaDevOps\Flexi\Infrastructure\Middlewares; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; class AuthCheckMiddleware implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // Perform authentication logic here and stop the execution chain if necessary // or pass the request return $handler->handle($request); } }
文档
文档可在网上获得,网址为https://flexi.cubadevops.com(建设中,尚未可用)。
贡献
欢迎贡献!请提交拉取请求或打开问题以讨论您想进行的任何更改。
许可证
Flexi 是一款开源软件,许可协议为 MIT 许可协议。