狼群 / router
简单路由与分发器实现。
v1.4.2
2024-07-09 21:57 UTC
Requires
- php: >=8.2
- psr/container: ^2.0
- psr/http-client: ^1.0
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- psr/log: ^3.0
- psr/simple-cache: ^3.0
- vulpes/http: v1.4
- vulpes/http-exceptions: v1.2
Requires (Dev)
- phpunit/phpunit: 10.2.6
README
可用方法
- ANY 对所有方法可用
- CLI 用于命令提示符
- GET 方法请求指定资源的表示。
- HEAD 方法请求与GET请求相同,但不包含响应体。
- POST 方法向指定资源提交实体,通常会导致服务器状态改变或副作用。
- PUT 方法用请求有效载荷替换目标资源的所有当前表示。
- DELETE 方法删除指定的资源。
- CONNECT 方法为指定的目标资源建立到服务器的隧道。
- OPTIONS 方法描述目标资源的通信选项。
- TRACE 方法在目标资源路径上执行消息回环测试。
- PATCH 方法对资源应用部分修改。
路径变体和中间件
<?php declare(strict_types=1); use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; require __DIR__ . '/vendor/autoload.php'; // composer require vulpes/container $container = new Container\Container; /** @var Psr\Container\ContainerInterface $container */ $dispatcher = new Http\Dispatcher(container: $container); // add anonymous Middleware globally as object $dispatcher->addMiddleware(new class implements MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // TODO before $response = $handler->handle($request); // TODO after return $response; } }); // add Middleware globally as string (the ContainerInterface will create it's instance) $dispatcher->addMiddleware(Middleware\AnotherMiddleware::class); // You can also insert middleware at the very beginning of the line, for example for error handling, // to catch the Http\Exception\NotFoundException thrown by the router $dispatcher->appendMiddleware(Middleware\ErrorHandlerMiddleware::class); $dispatcher // You can set prefix for paths via groups ->addGroup(name: 'rest-v1', path: 'api/v1') ->addMiddleware(Http\Middleware\JsonMiddleware::class) ->appendMiddleware('id-for-a-middleware-1') // You can use more groups for one simple path ->addGroup(name: 'rest-v2', path: 'api/v2') ->addMiddleware(Http\Middleware\JsonMiddleware::class) ->appendMiddleware('id-for-a-middleware-2') // You can use groups for simple authentication layers ->addGroup(name: 'admin') ->appendMiddleware('just-a-container-id-for-an-authentication-middleware') // add command line endpoint MyController->index() ->addPath(method: 'GET', path: '/', requestHandler: MyController::class . '::index') // add Middleware locally to current Path as string (classname), you can use object as well ->addMiddleware(Http\Middleware\JsonMiddleware::class) // add command line endpoint, MyController->service(int $thread) ->addPath(method: 'CLI', path: '/service/{thread:int}', requestHandler: MyController::class . '::service') // add command line endpoint, MyController->create() ->addPath( method: 'POST', // because of groups the full path will be: "/api/v1/entity/create", and "/api/v2/entity/create" path: '/entity/create', requestHandler: MyController::class . '::create', groups: 'rest-v1', 'rest-v2' ) // add Middleware locally to current path as string (classname), you can use object as well ->addMiddleware(Middleware\MyMiddleware::class) ->appendMiddleware(Middleware\AnotherErrorMiddleware::class) // The above middlewares will behave according to the pattern below (with global middlewares), with rest-v1 group // AnotherErrorMiddleware :before // id-for-a-middleware-1 :before // ErrorHandlerMiddleware :before // anonymous :before // AnotherMiddleware :before // JsonMiddleware :before // MyMiddleware :before // MyController->create() - throws Throwable, everything from controller // MyMiddleware :after // JsonMiddleware :after // AnotherMiddleware :after // anonymous :after // ErrorHandlerMiddleware :after - You can catch RouterInterface's NotFoundException here // id-for-a-middleware-1 :after // AnotherErrorMiddleware :after - ... or here // You can use RequestHandler (RequestHandlerInterface) as Controller too ->addPath(method: 'POST', path: '/entity/create', requestHandler: MyRequestHandler::class); // composer require vulpes/http $serverRequest = (new Http\Factory\ServerRequestFactory)->createServerRequestFromGlobals(); try { print $dispatcher->handle($serverRequest)/* ResponseInterface */->getBody(); } catch (Throwable $e) { print $e; }