Named Placeholders in Routes

In the Docs it shows how to get the named placeholders when using a closure and returning the response directly. But, how do you get access to the named placeholders when using controllers to return the response? There is no example of that in the docs.

I have searched, so please forgive me if this has been posted before.

Thank you

If I am correct, it’s actually pretty easy, simply set that variable name like this:

$app->get('/{lang}/', [HomeController::class, 'index'])->setArgument('lang', 'lang')->setName('home');

Then in the controller, add $lang

public function index(ResponseInterface $response, string $lang): ResponseInterface

Now $lang is available in the index method of the HomeController controller.

$app->get('/books/{id}', function ($request, $response, $args) {
  $args['placeHolder'] // $args['id']
}

@FvsJson That works, at least for me, when I return the response right there. But, not if I use a controller class. It errors with this message:

Unable to invoke the callable because no value was given for parameter 3 ($args)

That is with the route like this:

$route->get('/{lang}/dashboard', function ($request, $response, $args) {
    $args['lang'];
    DashboardController::class;
})->setName('dashboard');

and like this:

$route->get('/{lang}/dashboard', function ($request, $response, $args) {
    [$args['lang'], DashboardController::class];
})->setName('dashboard');

I am nearly certain that neither of those are correct. And, I am also certain that I am doing something incorrectly and hopefully obvious to someone else. :slight_smile:

If you print_r on $args what do you get? So the URL in question would look something like /eng/dashboard?

It doesn’t get that far, if I include the closure. It fails with the same error as listed above.

Yes, that is how the url would look.

Hmmm, I swear that I tried this several times and it failed each time, but this also seems to be working now.

$route->get('/{lang}/dashboard', DashboardController::class)->setName('dashboard');

and $lang is available in the controller

$route->get('/{lang}/dashboard', DashboardController::class)->setName('dashboard'); // are you calling __invoke method in here?

otherwise the router doesnt know what to call here?

//ie

$route->get('/{lang}/dashboard', DashboardController::class . ':indexAction')->setName('dashboard');

yes, __invoke method

This is working now. I don’t know why it wasn’t when I first posted, one of many things that I got wrong and still may have wrong.