Slim 4中如何通过中间件实现默认路由条件功能?
在Slim 4中实现全局路由参数正则校验(替代Slim 2的setDefaultConditions)
Slim 4 移除了Slim 2里的setDefaultConditions静态方法,但可以通过自定义全局中间件实现相同的全局路由参数正则校验效果,具体步骤如下:
1. 定义全局正则规则
先把需要校验的参数和对应的正则表达式整理成数组,和原有用法保持一致:
// 可放在配置文件或单独常量类中 $defaultConditions = [ 'product_id' => Regex::VALID_PRODUCT_ID, 'id' => Regex::VALID_NUM, 'cart_id' => Regex::VALID_CART_ID, 'session_id' => Regex::VALID_SESSION_ID, 'access_token' => Regex::VALID_ACCESS_TOKEN, ];
2. 创建全局校验中间件
编写中间件类,通过RouteContext获取当前路由参数,逐一匹配正则规则:
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; use Slim\Routing\RouteContext; class DefaultConditionsMiddleware implements MiddlewareInterface { private array $conditions; public function __construct(array $conditions) { $this->conditions = $conditions; } public function process(Request $request, RequestHandler $handler): Response { $routeContext = RouteContext::fromRequest($request); $route = $routeContext->getRoute(); // 无匹配路由时直接放行(如404请求) if (!$route) { return $handler->handle($request); } // 获取路由参数 $routeParams = $route->getArguments(); // 遍历校验参数 foreach ($this->conditions as $paramName => $regex) { if (isset($routeParams[$paramName]) && !preg_match("/^$regex$/", $routeParams[$paramName])) { // 参数不符合规则,返回自定义响应 $response = new \Slim\Psr7\Response(); return $response->withStatus(404) ->withHeader('Content-Type', 'application/json') ->getBody()->write(json_encode(['error' => "Invalid parameter: $paramName"])); } } // 校验通过,继续处理请求 return $handler->handle($request); } }
3. 注册全局中间件
在Slim应用实例中注册该中间件,使其对所有路由生效:
use Slim\Factory\AppFactory; require __DIR__ . '/vendor/autoload.php'; $app = AppFactory::create(); // 传入正则规则数组注册中间件 $app->add(new DefaultConditionsMiddleware($defaultConditions)); // 定义你的路由 $app->get('/products/{product_id}', function (Request $request, Response $response, $args) { // 此处的product_id已通过正则校验 $response->getBody()->write("Product ID: " . $args['product_id']); return $response; }); $app->run();
注意事项
- 正则表达式需用
^和$包裹,确保完整匹配,避免校验不严谨。 - 若需针对特定路由跳过校验,可在中间件中添加路由名称或路径的判断逻辑。
- 异常响应可根据业务需求调整,比如抛出自定义异常而非直接返回404。
内容的提问来源于stack exchange,提问作者Aniruddha
相关产品推荐
相关产品推荐

