jerowork / route-attribute-provider
使用PHP8属性定义路由
0.7.0
2024-05-28 13:07 UTC
Requires
- php: ^8.1
- jerowork/file-class-reflector: ^0.3
- psr/simple-cache: ^1.0 || ^2.0 || ^3.0
Requires (Dev)
- ergebnis/composer-normalize: ^2.15
- friendsofphp/php-cs-fixer: ^3.0
- mockery/mockery: ^1.4
- phpmd/phpmd: ^2.10
- phpro/grumphp-shim: ^1.4
- phpstan/phpstan: ^1.8
- phpunit/phpunit: ^9.5
- scrutinizer/ocular: ^1.8
- squizlabs/php_codesniffer: ^3.6
- symfony/cache: ^6.0
Suggests
- symfony/cache: As PSR-16 Cache implementation
README
使用PHP8属性定义路由。
安装
通过Composer安装
$ composer require jerowork/route-attribute-provider
配置
为了使用路由属性,选择任何现有的框架实现或创建一个自定义的。
实例化RouteAttributeConfigurator
在应用程序构建附近,例如在您的入口控制器中(或理想情况下注册到您的PSR-11容器中)。
基本配置
use Jerowork\RouteAttributeProvider\RouteAttributeConfigurator; // ... $routeConfigurator = new RouteAttributeConfigurator( new CustomRouteProvider($router) // Implementation of your choice ); $routeConfigurator ->addDirectory(sprintf('%s/src/Infrastructure/Api/Http/Action', __DIR__)) ->configure(); // ...
扩展配置
use Jerowork\FileClassReflector\FileFinder\RegexIterator\RegexIteratorFileFinder; use Jerowork\FileClassReflector\NikicParser\NikicParserClassReflectorFactory; use Jerowork\RouteAttributeProvider\RouteAttributeConfigurator; use Jerowork\RouteAttributeProvider\RouteLoader\ClassReflector\ClassReflectorRouteLoader; use PhpParser\NodeTraverser; use PhpParser\ParserFactory; // ... // All parts of the configurator can be replaced with a custom implementation $routeConfigurator = new RouteAttributeConfigurator( new CustomRouteProvider($router), // Implementation of your choice new ClassReflectorRouteLoader( new NikicParserClassReflectorFactory( new RegexIteratorFileFinder(), (new ParserFactory())->create(ParserFactory::PREFER_PHP7), new NodeTraverser() ) ) ); // Multiple directories can be defined $routeConfigurator ->addDirectory( sprintf('%s/src/Infrastructure/Api/Http/Action', __DIR__), sprintf('%s/src/Other/Controller', __DIR__) ) ->configure(); // ...
现有实现
- jerowork/slim-route-attribute-provider for Slim
- brenoroosevelt/league-route-attribute-provider for League/Route
或者查看packagist以获取其他实现。
自定义实现
使用RouteAttributeProviderInterface
创建自定义实现。
一个(虚构的)自定义实现
use Jerowork\RouteAttributeProvider\Api\Route; use Jerowork\RouteAttributeProvider\RouteAttributeProviderInterface; final class CustomRouteProvider implements RouteAttributeProviderInterface { private SomeRouter $router; public function __construct(SomeRouter $router) { $this->router = $router; } public function configure(string $className,string $methodName, Route $route) : void { // Register rule at your router $rule = $this->router->addRule( $route->getMethods(), $route->getPattern(), $className.':'.$methodName, $route->getName() ); // Register optional middleware foreach ($route->getMiddleware() as $middleware) { $rule->addMiddleware($middleware); } } }
缓存
默认情况下,路由属性缓存是禁用的。这对于开发环境来说是可以的。
然而,对于生产环境,您应该使用更高效的路线属性加载方式。因此,您可以使用任何PSR-16缓存实现。
use Symfony\Component\Cache\Adapter\ApcuAdapter; use Symfony\Component\Cache\Psr16Cache; // ... // Enable route attribute caching with any PSR-16 implementation (e.g. symfony/cache) $routeConfigurator->enableCache(new Psr16Cache(new ApcuAdapter())); // ...
注意:也可以使用任何PSR-6缓存实现,通过使用Symfony的PSR-6到PSR-16适配器。
用法
可以通过PHP8属性定义路由。
最小化示例
use Jerowork\RouteAttributeProvider\Api\Route; use Psr\Http\Message\ResponseInterface as ServerRequest; use Psr\Http\Message\ServerRequestInterface as Response; final class RootAction { #[Route('/root')] public function __invoke(ServerRequest $request, Response $response) : Response { return $response; } }
扩展示例
use Jerowork\RouteAttributeProvider\Api\RequestMethod; use Jerowork\RouteAttributeProvider\Api\Route; use Psr\Http\Message\ResponseInterface as ServerRequest; use Psr\Http\Message\ServerRequestInterface as Response; final class RootAction { #[Route('/root', method: RequestMethod::GET, name: 'root', middleware: SomeMiddleware::class)] public function __invoke(ServerRequest $request, Response $response) : Response { return $response; } }
完整示例
use Jerowork\RouteAttributeProvider\Api\RequestMethod; use Jerowork\RouteAttributeProvider\Api\Route; use Psr\Http\Message\ResponseInterface as ServerRequest; use Psr\Http\Message\ServerRequestInterface as Response; final class RootAction { #[Route('/root', method: [RequestMethod::GET, RequestMethod::POST], name: 'root', middleware: [ SomeMiddleware::class, AnotherMiddleware::class, ], host: 'localhost', schemes: ['http', 'https'], httpPort: 8888, httpsPort: 9999, options: ['strategy' => 'something'] )] #[Route('/second-route', method: RequestMethod::DELETE, name: 'second-route' )] public function __invoke(ServerRequest $request, Response $response) : Response { return $response; } }