ellipse / router-fastroute

FastRoute Psr-15 中间件和请求处理器

1.0.3 2018-03-19 16:25 UTC

This package is auto-updated.

Last update: 2024-08-26 01:07:45 UTC


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\SimpleDispatcherEllipse\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);