ellipse / router-fastroute
FastRoute Psr-15 中间件和请求处理器
Requires
- php: >=7.0
- ellipse/router-adapter: ^1.0
- ellipse/type-errors: ^1.0
- nikic/fast-route: ^1.2
- psr/http-message: ^1.0
Requires (Dev)
- eloquent/phony-kahlan: ^1.0
- kahlan/kahlan: ^4.0
README
FastRoute Psr-15 中间件和请求处理器。
要求 php >= 7.0
安装 composer require ellipse/router-fastroute
运行测试 ./vendor/bin/kahlan
作为请求处理器的使用
此包提供了一个使用 fastroute 分发器工厂作为参数的 Ellipse\Router\FastRouteRequestHandler
Psr-15 请求处理器。
此工厂可以返回任何可调用的实现 FastRoute\Dispatcher
的实例,并且匹配的路线处理程序应预期为 Psr\Http\Server\RequestHandlerInterface
的实现。
当 FastRouteRequestHandler
处理请求时,由工厂产生的 Dispatcher
用于匹配 Psr-15 请求处理器。当匹配的路线模式包含占位符时,将创建一个新的请求,其中包含占位符 => 匹配值对作为请求属性。最后,通过此新请求代理匹配的请求处理器以返回响应。
使用工厂可以在处理请求时执行耗时任务,只需使用 FastRouteRequestHandler
处理请求即可。如果出于某种原因,应用程序使用其他请求处理器处理传入请求,则不会为该请求映射路线而浪费时间。
关于异常
- 当工厂不返回
FastRoute\Dispatcher
的实现时,会抛出Ellipse\Router\Exceptions\FastRouteDispatcherTypeException
。 - 当 fastroute 分发器匹配的路线处理程序不是
Psr\Http\Server\RequestHandlerInterface
的实现时,会抛出Ellipse\Router\Exceptions\MatchedHandlerTypeException
。 - 当没有路线匹配 URL 时,会抛出
Ellipse\Router\Exceptions\NotFoundException
。 - 当路线匹配 URL 但请求 HTTP 方法不被匹配的路线允许时,会抛出
Ellipse\Router\Exceptions\MethodNotAllowedException
。
<?php namespace App; use FastRoute\RouteParser; use FastRoute\DataGenerator; use FastRoute\Dispatcher; use FastRoute\RouteCollector; use Ellipse\Router\FastRouteRequestHandler; // Get a psr7 request. $request = some_psr7_request_factory(); // Create a fastroute dispatcher factory. $factory = function ($r) { // Create a new fastroute route collector. $r = new RouteCollector( new RouteParser\Std, new DataGenerator\GroupCountBased ); // The route handlers must be Psr-15 request handlers. $r->get('/', new SomeRequestHandler); // When this route is matched a new request with an 'id' attribute would be passed to the request handler. $r->get('/path/{id}', new SomeOtherRequestHandler); // return a fastroute dispatcher return new Dispatcher\GroupCountBased($r->getData()); }; // Create a fastroute request handler using this factory. $handler = new FastRouteRequestHandler($factory); // When a route is matched the request is handled by this route request handler. // Otherwise NotFoundException or MethodNotAllowedException is thrown $response = $handler->handle($request);
作为中间件的使用
此包提供了一个使用 fastroute 分发器工厂作为参数的 Ellipse\Router\FastRouteMiddleware
Psr-15 中间件。
底层它使用给定的工厂创建一个 FastRouteRequestHandler
并使用它来处理请求。当抛出 NotFoundException
时,将请求处理委托给下一个中间件。
<?php namespace App; use FastRoute\RouteParser; use FastRoute\DataGenerator; use FastRoute\Dispatcher; use FastRoute\RouteCollector; use Ellipse\Router\FastRouteMiddleware; // Get a psr7 request. $request = some_psr7_request_factory(); // Create a fastroute dispatcher factory. $factory = function ($r) { // Create a new fastroute route collector. $r = new RouteCollector( new RouteParser\Std, new DataGenerator\GroupCountBased ); // The route handlers must be Psr-15 request handlers. $r->get('/', new SomeRequestHandler); // When this route is matched a new request with an 'id' attribute would be passed to the request handler. $r->get('/path/{id}', new SomeOtherRequestHandler); // return a fastroute dispatcher return new Dispatcher\GroupCountBased($r->getData()); }; // Create a fastroute middleware using this factory. $middleware = new FastRouteMiddleware($factory); // When a route is matched the request is handled by this route request handler. // When a NotFoundException is thrown, NextRequestHandler is used to handle the request. $response = $middleware->process($request, new NextRequestHandler);
基于分组计数的中间件和请求处理器
由于 fastroute 分发器通常是基于分组计数的,因此此包提供了一个 Ellipse\Router\FastRoute\GroupCountBasedMiddleware
和一个 Ellipse\Router\FastRoute\GroupCountBasedRequestHandler
,它只接受一个路线定义回调参数,允许轻松创建基于分组计数的 fastroute 中间件和请求处理器。
<?php namespace App; use Ellipse\Router\FastRoute\GroupCountBasedMiddleware; use Ellipse\Router\FastRoute\GroupCountBasedRequestHandler; // Create a route definition callback. $routeDefinitionCallback = function ($r) { // The route handlers must be Psr-15 request handlers. $r->get('/', new SomeRequestHandler); // When this route is matched a new request with an 'id' attribute would be passed to the request handler. $r->get('/path/{id}', new SomeOtherRequestHandler); }; // Create a fastroute middleware using a group count based dispatcher. $middleware = new GroupCountBasedMiddleware($routeDefinitionCallback); // Create a fastroute request handler using a group count based dispatcher. $handler = new GroupCountBasedRequestHandler($routeDefinitionCallback);
分发器工厂辅助工具
此包提供了两个分发器工厂辅助工具,代理 fastroute 的那些:Ellipse\Router\FastRoute\SimpleDispatcher
和 Ellipse\Router\FastRoute\CachedDispatcher
。
这两个类只是可调用的代理,它们分别代理其各自的 fastroute 函数,在 FastRouteRequestHandler
处理请求时生成分发器。
<?php namespace App; use Ellipse\Router\FastRouteMiddleware; use Ellipse\Router\FastRouteRequestHandler; use Ellipse\Router\FastRoute\SimpleDispatcher; // Create a route definition callback like with fastroute simpleDispatcher function. $routeDefinitionCallback = function ($r) { // The route handlers must be Psr-15 request handlers. $r->get('/', new SomeRequestHandler); // When this route is matched a new request with an 'id' attribute would be passed to the request handler. $r->get('/path/{id}', new SomeOtherRequestHandler); }; // An optional array of options can be passed like with fastroute simpleDispatcher function. $options = [ // Can specify fastroute classes to use. ]; // Create a dispatcher factory using fastroute simpleDispatcher function. // Same with CachedDispatcher using fastroute cachedDispatcher. $factory = new SimpleDispatcher($routeDefinitionCallback, $options); // Create a fastroute middleware using this dispatcher factory. $middleware = new FastRouteMiddleware($factory); // Create a fastroute request handler using this dispatcher factory. $handler = new FastRouteRequestHandler($factory);