路由中间件 RouterMiddleware
路由中间件 ConstanzeStandard\Fluff\Middleware\RouterMiddleware
为 Fluff 添加了路由功能。
它将我们添加的路由数据与 request 进行匹配,然后通过 request 的 attribute 向内核传递匹配后的调度信息 (dispatch data
).
添加一条路由
use ConstanzeStandard\Fluff\Middleware\RouterMiddleware;
use Psr\Http\Server\MiddlewareInterface;
$routerMiddleware = new RouterMiddleware();
/**
* @var array|string $httpMethods
* @var string $pattern
* @var mixed $target
* @var MiddlewareInterface[] $middlewares
* @var string $name
*/
$routerMiddleware->withRoute($httpMethods, $pattern, $target, $middlewares, $name);
withRoute
方法接受一组 Route
信息,按参数顺序分别是:
- HTTP method, 可以为数组或字符串,如
['GET', 'POST']
或'GET'
- URL 的匹配模式,是形如一个 URL 的字符串,通过
{}
标记的部分会被解析成 URL 参数。(i.e./user/{id}
). - 执行目标的信息。框架的执行目标是一个
callable
对象,类似controller
的对象,而第三个参数就是用于获取这个对象的信息,如Target@index
;也可以直接传入这个callable
对象。 - 绑定到当前
Route
上的中间件列表,遵循后进先出的原则,排在前面的中间件后执行。这个参数是可选的。 - 当前
Route
的名称,这个参数是可选的。
withRoute
方法返回一个 ConstanzeStandard\Fluff\Component\Route
对象,你可以利用这个对象的 addMiddleware
方法继续向 Route
添加中间件,或通过 setName
方法设置名称。
代理方法
use Psr\Http\Server\MiddlewareInterface;
/**
* @var string $pattern
* @var mixed $target
* @var MiddlewareInterface[] $middlewares
* @var string $name
*/
$routerMiddleware->get($pattern, $target, $middlewares, $name);
$routerMiddleware->post($pattern, $target, $middlewares, $name);
$routerMiddleware->put($pattern, $target, $middlewares, $name);
$routerMiddleware->delete($pattern, $target, $middlewares, $name);
$routerMiddleware->options($pattern, $target, $middlewares, $name);
ConstanzeStandard\Fluff\Middleware\RouterMiddleware::withRoute
包含一组代理方法,分别是 get
, post
, put
, delete
, options
方法,它们与 withRoute
方法的行为完全一致,只是分别指代了 GET
, POST
, PUT
, DELETE
, OPTIONS
的 http method. 可以使用它们简化代码。
添加路由组
use ConstanzeStandard\Fluff\Middleware\RouterMiddleware;
use Psr\Http\Server\MiddlewareInterface;
$routerMiddleware = new RouterMiddleware();
/**
* @var string $prefixPattern
* @var MiddlewareInterface[] $middlewares
*/
$routerMiddleware->withGroup($prefixPattern, $middlewares, function (RouterMiddleware $router) {
$router->withRoute(...);
});
使用 withGroup
方法对路由进行分组,接受三个参数,按参数顺序分别是:
- URL 的匹配模式的前缀,与
$pattern
一样,可以通过{}
标记 URL 参数。 - 当前组的中间件列表,这些中间件会添加进组内的每一个
Route
中。 - 一个回到函数,它接受
RouterMiddleware
对象自身作为唯一参数,你可以通过它,在回调函数中添加路由。
添加全局中间件
use ConstanzeStandard\Fluff\Middleware\RouterMiddleware;
use Psr\Http\Server\MiddlewareInterface;
$routerMiddleware = new RouterMiddleware();
/** @var MiddlewareInterface $middleware */
$routerMiddleware->addMiddleware($middleware);
通过 addMiddleware
方法添加的中间件会追加到每一个 Route
中,中间件的顺序与添加的顺序有关,全局的中间件与 Route
私有的中间件共同遵循后进先出
的原则,在后面添加的中间件先被执行。
/**
* @var MiddlewareInterface $middleware1
* @var MiddlewareInterface $middleware2
* @var MiddlewareInterface $middleware3
* @var MiddlewareInterface $middleware4
* @var MiddlewareInterface $middleware5
* @var MiddlewareInterface $middleware6
*/
$routerMiddleware->addMiddleware($middleware1);
$routerMiddleware->withGroup('', [$middleware2, $middleware3], function($router) {
$routerMiddleware->get('/user/{name}', 'Target@index')->addMiddleware($middleware4)->addMiddleware($middleware5);
});
$routerMiddleware->addMiddleware($middleware6);
如上所示,这六个中间件的执行顺序是:$middleware6
-> $middleware5
-> $middleware4
-> $middleware3
-> $middleware2
-> $middleware1
.
路由解析器
use ConstanzeStandard\Fluff\Middleware\RouterMiddleware;
$routerMiddleware = new RouterMiddleware();
$routeParser = $routerMiddleware->getRouteParser();
$routeParser->setHost('http://localhost');
/**
* Get the relative url by route name.
*
* @var string $name
* @var array $params
* @var array $queryParams
*/
$url = $routeParser->getRelativeUrlByName($name, $params, $queryParams);
$url = $routeParser->getUrlByName($name, $params, $queryParams);
getRouteParser
方法可以获取一个 Route 解析器,该解析器包含三个方法:
setHost
方法设置 host,在获取完整 URL 时用到。(i.e.http://localhost
)getRelativeUrlByName
根据 Route 的名称获取相对 URL 路径。第一个参数为 Route 名称;第二个参数为 URL 参数,如/user/{id}
可以传入['id' => 10]
来补全路径;第三个参数是一个数组,用来定义后面附带的 GET 参数。getUrlByName
与getRelativeUrlByName
基本一致,但getUrlByName
获取的是完整 URL 路径。
构造方法
use ConstanzeStandard\Fluff\Middleware\RouterMiddleware;
use ConstanzeStandard\Route\Interfaces\CollectionInterface;
/**
* @var CollectionInterface $collection
* @var string $dispathDataFlag
*/
$routerMiddleware = new RouterMiddleware($collection, $dispathDataFlag);
RouterMiddleware
的构造方法接受两个参数,按参数顺序分别是:
- 一个
ConstanzeStandard\Route\Interfaces\CollectionInterface
的实例,默认为ConstanzeStandard\Route\Collector
, 这个参数让你有机会换掉它。 - 当路由匹配成功后,会生成
dispatch data
, 并将它传入绑定到server request
的 attribute 上,这个参数就是 attribute 的索引值,默认是ConstanzeStandard\Fluff\Component\DispatchData::ATTRIBUTE_NAME
的值,这个参数让你有机会匹配自定义 handler。请不要改变它,除非你知道自己在做什么。