After upgrading to Slim v4 I'm trying to replace my simple $app->subRequest call with $app->handle as specified in the changelog. However there are no details on how to do this in either the changelog or upgrade guide and my best effort to fix it ends up creating an infinite loop:
$app->get("/foo", function (Request $req) use ($app) {
$uri = $req->getUri();
$newUri = $uri->withPath("/bar");
$barReq = $req->withUri($newUri);
// Here we get stuck in endless loop instead of ending up in the /bar route handler below
$app->handle($barReq);
});
$app->get("/bar", function (Request $req) use ($app) {
echo 'bar!';
die;
});
It's like even though $barReq is a new request object with a completely new uri (and path) the router does not resolve which route handler that should handle it, instead it's just handled by the same one again.
My previous simplified (v3) code looked like and worked fine to get the result of the /bar route when calling /foo:
$app->get("/foo", function (Request $req) use ($app) {
$app->subRequest('GET', '/bar');
});
I'm probably missing some central concept on how Slim 4 handles requests and routes internally and would appreciate some help!
Edit: Should perhaps add that what I mean with internal redirect is that client should not be aware that a redirect has been made. I.e. any regular redirect function returning something to client is not applicable here.
As @remy stated, use the ServerRequestFactory implementing ServerRequestFactoryInterface.
For slim/psr7 it is: Slim\Psr7\Factory\ServerRequestFactory
A silent redirect to another route is then as simple as:
use Slim\Psr7\Factory\ServerRequestFactory;
...
...
$app->get('/foo', function ($request, $response, $args)
{
global $app;
return $app
->handle((new ServerRequestFactory())->createServerRequest('GET', '/bar'));
});