Accessing route parameters in middleware in Slim 4
Asked Answered
E

1

6

I would like to know how I can access route parameter in a middleware in Slim 4.

Provided I define a route with placeholder and attached middleware:

<?php

// ...

$app
    ->get('/{userId}', Controller::class)
    ->add(Middleware::class);

I would like to access value of {userId} from middleware before the controller is inovked:

class Middleware
{
    function __invoke($request, $handler)
    {
        // Resolve user ID in this scope?..
        return $handler->handle($request);
    }
}

I know that in Slim 3 we could do it accessing attributes of request object, however, it does not work in Slim 4. The attributes of route object contain the following entries:

  • __routingResults__
  • __route__
  • __basePath__

Non of these seems to contain parameters.

Etesian answered 22/4, 2020 at 23:4 Comment(0)
P
10

What you need is documented here. You can create the route context, and the route object itself, using the request object in your middleware. Just keep in mind that you have to add routing middleware for this to work. Here is an example:

<?php                                                                                                                                                                    
use Slim\Factory\AppFactory;                                                                                                                                             
use Slim\Routing\RouteContext;                                                                                                                                           

require __DIR__ . '/../vendor/autoload.php';                                                                                                                             

// Create App                                                                                                                                                            
$app =  AppFactory::create();                                                                                                                                            

Class Middleware                                                                                                                                                         
{                                                                                                                                                                        
    function __invoke($request, $handler)                                                                                                                                
    {                                                                                                                                                                    
        $routeContext = RouteContext::fromRequest($request);                                                                                                             
        $route = $routeContext->getRoute();                                                                                                                              
        // Resolve user ID in this scope                                                                                                                                 
        $id = $route->getArgument('id');                                                                                                                                 
        $response = $handler->handle($request);                                                                                                                          
        $response->getBody()->write("Route parameter value (in middleware): {$id}");                                                                                     
        return $response;                                                                                                                                                
    }                                                                                                                                                                    
}                                                                                                                                                                        

$app->get('/{id}', function($request, $response, $args) {                                                                                                                
    return $response;                                                                                                                                                    
})->add(Middleware::class);                                                                                                                                              

$app->addRoutingMiddleware();                                                                                                                                            

// Run app                                                                                                                                                               
$app->run();

Now try visiting /1 or /2 and you see the middleware is aware of the parameter value.

Patric answered 23/4, 2020 at 6:27 Comment(2)
Thank you, this worked for me. Looks somewhat cumbersome, but indeed this is according to documentation. Have a nice day!Etesian
I could not figure out how to do this after upgrading from Slim 3. Thank you.Suckling

© 2022 - 2024 — McMap. All rights reserved.