Slim 4 替换subRequest为handle实现内部跳转出现无限循环问题求助
问题根因
Slim 4 完成首次路由匹配后,会将路由结果存储在请求对象的routingResults属性中,后续调用$app->handle()处理同一个请求对象衍生的实例时,默认会复用已有的路由结果,不会重新执行路由匹配。所以你就算修改了URI路径,还是会触发原来的/foo路由逻辑,进而陷入无限循环。
解决代码
你需要在构造新的请求对象后,手动移除已有的路由结果属性,强制Slim重新执行路由匹配即可:
$app->get("/foo", function (\Psr\Http\Message\ServerRequestInterface $req) use ($app) { $uri = $req->getUri(); $newUri = $uri->withPath("/bar"); $barReq = $req->withUri($newUri); // 移除已有的路由结果,强制重新匹配路由 $barReq = $barReq->withoutAttribute('routingResults'); // 执行内部请求获取响应后直接返回 return $app->handle($barReq); }); $app->get("/bar", function (\Psr\Http\Message\ServerRequestInterface $req) { $response = new \Slim\Psr7\Response(); $response->getBody()->write('bar!'); return $response; });
注意事项
- 不要在路由回调里用
die或者直接echo输出内容,Slim 4 遵循PSR-7规范,所有响应都需要返回Response对象,否则可能出现输出异常。 - 如果内部请求需要修改请求方法、传参等,可以直接通过请求对象的
withMethod、withQueryParams、withParsedBody等方法修改后再传入handle方法。 - 该方案完全为服务端内部处理,客户端不会感知到任何跳转行为,符合需求。
内容的提问来源于stack exchange,提问作者Anders Gustafsson
相关产品推荐
相关产品推荐

