Route Parameters
Most real routes need to capture part of the URL as data — a user ID, a product slug, and so on. Slim lets you define these dynamic segments right inside the route pattern using curly braces.
Dynamic Segments with Curly Braces
Wrap a placeholder name in { } anywhere in the route path:
$app->get('/users/{id}', function ($request, $response, $args) {
$id = $args['id'];
$response->getBody()->write("Showing user " . $id);
return $response;
});
A request to /users/42 matches this route and Slim populates $args with
['id' => '42']. Note that placeholder values always arrive as strings — cast with
(int) if you need a number.
Reading Values from $args
Every named placeholder in the route becomes a key in the $args array, in the third
parameter of your handler closure — you simply index into it by name:
$name = $args['id']; // value from the matched {id} segment
Optional Parameters
Wrap a trailing segment in square brackets to make it optional. If the visitor omits it, the argument
simply won't be present in $args:
$app->get('/greet/{firstName}[/{lastName}]', function ($request, $response, $args) {
$greeting = "Hello, " . $args['firstName'];
if (isset($args['lastName'])) {
$greeting .= " " . $args['lastName'];
}
$response->getBody()->write($greeting);
return $response;
});
Both /greet/Sonu and /greet/Sonu/Pandit match this single route definition.
Constraining a Parameter with a Regex Pattern
Append :pattern after the placeholder name to restrict what it can match. This is useful
for making sure an id segment only matches digits, so it doesn't accidentally swallow other
routes:
$app->get('/users/{id:[0-9]+}', function ($request, $response, $args) {
$response->getBody()->write("Numeric user ID: " . $args['id']);
return $response;
});
With this pattern, /users/42 matches but /users/abc does not — Slim will fall
through to a 404 (or another matching route) instead of running this handler with bad data.
Worked Example: Two Parameters in One Route
Routes can capture more than one dynamic segment. Here both a product ID and a review ID are read from the URL:
$app->get('/products/{id:[0-9]+}/reviews/{reviewId:[0-9]+}', function ($request, $response, $args) {
$productId = $args['id'];
$reviewId = $args['reviewId'];
$response->getBody()->write(
"Review " . $reviewId . " for product " . $productId
);
return $response;
});
A request to /products/7/reviews/103 matches, and $args holds ['id' => '7', 'reviewId' => '103'] — both readable by name inside the handler.