You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slim Framework 4中间件获取所有路由返回500错误问题

问题根因

接口返回500由三类问题共同导致:

  • 中间件不符合Slim执行规范:__invoke方法必须返回Psr\Http\Message\ResponseInterface实例,你的代码执行print_r后直接终止,没有返回响应对象,框架会直接抛出类型错误。
  • 冗余容器配置:Slim框架启动时已经自动完成RouteCollectorInterface的实例绑定,你自定义的绑定闭包如果在App实例初始化完成前执行,会拿到未注册路由的空收集器实例。
  • 中间件挂载顺序错误:Slim中间件是外层先执行、内层后执行的栈结构,如果你的ACLMiddleware挂载在框架自带的RoutingMiddleware外层,执行到你的逻辑时路由还未完成解析,无法拿到有效路由数据。
修复步骤

1. 修正中间件代码

优先从请求上下文获取路由收集器,不需要手动依赖注入,最后必须返回处理后的响应对象:

namespace App\Application\Middleware;

use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
use Slim\Routing\RouteContext;

final class ACLMiddleware
{
    public function __invoke(Request $request, RequestHandler $handler): Response
    {
        // 从请求中获取路由上下文,路由解析完成后才能正常读取
        $routeContext = RouteContext::fromRequest($request);
        $routeCollector = $routeContext->getRouteCollector();
        // 获取所有已注册路由
        $routes = $routeCollector->getRoutes();
        
        // 调试输出建议加exit终止,或写入日志避免破坏响应结构
        print_r($routes);
        exit;

        // 正式逻辑请删除调试代码,正常执行后续中间件并返回响应
        // $response = $handler->handle($request);
        // return $response;
    }
}

2. 清理冗余配置

删除容器配置中自定义的RouteCollectorInterface::class绑定闭包,框架默认绑定的实例可以直接使用,不需要手动覆盖。

3. 调整中间件挂载顺序

保证ACLMiddleware挂载在RoutingMiddleware内层(即比RoutingMiddleware晚添加),确保执行ACL逻辑时路由已经完成解析:

<?php
// 先添加路由中间件,会在栈内层先执行完成路由解析
$app->add(\Slim\Middleware\RoutingMiddleware::class);
// 后添加ACL中间件,在栈外层执行时路由已经解析完毕
$app->add(\App\Application\Middleware\ACLMiddleware::class);
// 错误中间件可以放在最外层
$app->addErrorMiddleware(true, true, true);

补充说明:如果需要获取当前请求匹配到的单条路由,直接调用$routeContext->getRoute()即可,不需要遍历全量路由列表。

内容的提问来源于stack exchange,提问作者Laercio Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:09:47