有时只需要给某个路由单独添加中间件
编辑core/RouteItem.php
,内容如下
<?php
namespace core;
class RouteItem {
public function __construct(public string $method, public string $uri, public \Closure | string $cb, public array $middleware) { }
}
编辑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
,内容如下
<?php
namespace core;
class Controller {
public array $middlewares = [];
public function __construct(string $method, array $middlewares, Request $request, Response $response) {
$this->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
,内容如下
<?php
namespace app\middleware;
use core\Request;
use core\Response;
class Route {
public function handle(Request $request, Response $response, \Closure $next): void {
echo 'Route(路由) 中间件 call before<br>';
$next();
echo 'Route(路由) 中间件 call after<br>';
}
}
编辑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
请先登录
可以看出,目前中间件的执行顺序是全局->路由分组->控制器->路由
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。