I have a pretty straightforward question. I am using Slim 3 to build a RESTfull api.
How come this works:
$app->get('/news[/{params:.*}]', function ($request, $response, $args) {
$params = explode('/', $request->getAttribute('params'));
$response->write("news!");
return $response;
});
But not this:
$app->get('/news[/{params:.*}]/details', function ($request, $response, $args) {
$params = explode('/', $request->getAttribute('params'));
$response->write("news details");
return $response;
});
In fact the latter does not compile.
Using unlimited Optional segments, implies that each consequent segment is reserved.
In your defined route for /news[/{params:.*}]
the following paths qualify:
/news
/news/foo
/news/foo/bar
/news/foo/bar/...
So adding an extra fixed segment /details
won't work if you add it after the square brackets.
When you define it as /news[/{params:.*}/details]
with the /details
segment within the square brackets it does work for details, but not in combination with the first route & will break. You can still go with your first route & check the last param, or with an optional param within:
$app->get('/news[/{params:.*}[/details]]', function ($request, $response, $args) {
$params = explode('/', $request->getAttribute('params'));
if (end($params) != 'details') {
$response->write("news!");
} else {
// $params for details;
array_pop($params);
$response->write("news details");
}
// $params is an array of all the optional segments
var_dump($params);
});
Update:
The actual problem here seems like a colliding definition in the routes, where for example the unlimited optional segments would always match the second defined route. It can be solved by defining the routes with a route regex & enclosing them in a route group prior to non-colliding matches:
$app->group('/news', function () {
$this->map(['GET'], '', function ($request, $response, $args) {
$response->write("news w/o params");
})->setName('news');
// Unlimited optional parameters not ending with "/details"
$this->get('/{params:[[:alnum:]\/]*[^\/details]}', function ($request, $response, $args) {
$params = explode('/', $request->getAttribute('params'));
var_dump($params);
$response->write("news!");
});
// Unlimited optional parameters ending with "/details"
$this->get('/{params:[[:alnum:]\/]*\/details}', function ($request, $response, $args) {
$params = explode('/', $request->getAttribute('params'));
array_pop($params); // fix $params
var_dump($params);
$response->write("news details");
});
});