有时只需要给某个路由单独添加中间件
编辑core/RouteItem.php
,内容如下
编辑core/Route.php
,修改addRoute
方法
public function addRoute(string $method, string $uri, \Closure | string $cb, $middleware): void {
$method = strtoupper($method);
slash_add($uri);
$middlewares = [];
if ($middleware && is_array($middleware)) {
$middlewares = $middleware;
} else if ($middleware) {
$middlewares[] = $middleware;
}
$item = new RouteItem($method, $uri, $cb, $middlewares);
$this->routes[] = $item;
}
编辑core/Router.php
,修改如下方法
public function get(string $uri, \Closure | string $cb, $middleware = null): void {
$this->curr->addRoute('get', $uri, $cb, $middleware);
}
public function post(string $uri, \Closure | string $cb, $middleware = null): void {
$this->curr->addRoute('post', $uri, $cb, $middleware);
}
public function put(string $uri, \Closure | string $cb, $middleware = null): void {
$this->curr->addRoute('put', $uri, $cb, $middleware);
}
public function delete(string $uri, \Closure | string $cb, $middleware = null): void {
$this->curr->addRoute('delete', $uri, $cb, $middleware);
}
public function patch(string $uri, \Closure | string $cb, $middleware = null): void {
$this->curr->addRoute('patch', $uri, $cb, $middleware);
}
public function options(string $uri, \Closure | string $cb, $middleware = null): void {
$this->curr->addRoute('options', $uri, $cb, $middleware);
}
public function any(string $uri, \Closure | string $cb, $middleware = null): void {
$methods = ['get', 'post', 'put', 'delete', 'patch', 'options'];
foreach ($methods as $method) {
$this->curr->addRoute($method, $uri, $cb, $middleware);
}
}
修改start
方法
private function start(RouteItem $item, string $namespace, Request $request, Response $response): void {
if ($item->cb instanceof \Closure) {
($item->cb)($request, $response);
} else {
[$controller, $method] = explode('@', $item->cb);
$module = "$namespace\\$controller";
new $module($method, $item->middleware, $request, $response);
}
}
编辑core/Controller.php
,内容如下
applyMiddleware(array_merge($this->middlewares, $middlewares), $method, $request, $response);
}
private function applyMiddleware(array $middlewares, string $method, Request $request, Response $response): void {
if (!empty($middlewares)) {
$middleware = array_shift($middlewares);
$next = function () use ($middlewares, $method, $request, $response) {
$this->applyMiddleware($middlewares, $method, $request, $response);
};
call_user_func_array([new $middleware(), 'handle'], [$request, $response, $next]);
} else {
$this->{$method}($request, $response);
}
}
}
新建 app/middleware/Route.php
,内容如下
';
$next();
echo 'Route(路由) 中间件 call after
';
}
}
编辑route/user.php
,为login
路由添加中间件
$router->get('login', 'User@login', \app\middleware\Route::class);
$router->get('logout', 'User@logout');
测试
浏览器访问http://phpapi.com/user/login
或者http://phpapi.com/user/logout
,这里随机模拟了登录判断
当登录成功时,会输出
All(全局) 中间件 call before
Group(路由分组) 中间件 call before
User(控制器) 中间件 call before
Route(路由) 中间件 call before
Route(路由) 中间件 call after
User(控制器) 中间件 call after
Group(路由分组) 中间件 call before
All(全局) 中间件 call after
from /user/login
当登录失败时,会输出
All(全局) 中间件 call before
Group(路由分组) 中间件 call before
All(全局) 中间件 call after
请先登录
可以看出,目前中间件的执行顺序是全局->路由分组->控制器->路由