How to get all routes who use middleware only?


#1

I want to know which routes who use the middlewares?

Is it possible? Because I dont know which function to make this possible? I have try with getCallable() or getMiddleware() but not work.

Here is what I tried :
$app->map([‘GET’,‘POST’],’/test/route’,function(Request $request, Response $response) use($container) {
$body = $request->getBody();
$routes = $container->get(‘router’)->getRoutes();
foreach($routes as $route){
$data[] = [
‘pattern’ => $route->getPattern(),
‘methods’ => $route->getMethods(),
‘middleware’ => $route->getMiddleware(),
‘callable’ => $route->getCallable()
];
}
$body->write(json_encode($data,JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT));
return $response
->withHeader(‘Content-Type’,‘application/json; charset=utf-8’)
->withBody($body);
});

Some of my route using middleware but I got null :
{
“pattern”: “/edit-profile/{username}”,
“methods”: [
“POST”
],
“middleware”: [
{},
{},
{}
],
“callable”: {}
}

Note: I have set determineRouteBeforeAppMiddleware to true


#2

You can get the matching route from the $request object.

Example:

/** @var \Slim\Route|null $route */
$route = $request->getAttribute('route');

if (!$route) {
    // no matching route found
    return $next($request, $response);
}

// here you have the route...

Tipp: Better don’t use the use($container) language construct to “import” a “global variable”. Better use $this within the routing callback function. Example: $logger = $this->get('logger');


#3

Thanks for your reply, but I was wrong to create the subject (I’ve edited this, to make clear about what I want to achieve).

Actualy, I want to get all routes in array, but only routes who use middleware, for example I just want to get which one routes who use session middleware.in array?

My problem is I dont know how to determine the middleware name.

The reason I use $container is to get all routes.


#4

I think this is not possible now in Slim

I think easiest (not prettiest) way would be create some static class with array and in each middleware “register” middleware usage

class YourMiddlewareCallStack { 
    private static $array = []; 
    public static function add($string) {self::$array[] = $string; }
    public static function getAll() {return self::$array; }
}

call this inside all your middlewares:

YourMiddlewareCallStack::add('some middleware name'); 

then, in your controller, just check if middleware name is in that array

in_array('middleware name your are looking for', YourMiddlewareCallStack::getAll() );

if you are using classes with __invoke as middleware it would be even easier and prettier


#5

Thanks dude, Now I got idea how to make this better.


#6

I think the json_encode function doesn’t support encoding of PHP callbacks / closures. For this reason the ‘middleware’ element is empty. Maybe use Xdebug or something else to see more details.

Here is a working example that shows true if a middleware exists per route.


$app->map(['GET', 'POST'], '/route', function (Request $request, Response $response) {
    $body = $request->getBody();

    /** @var \Slim\Route[] $routes */
    $routes = $this->get('router')->getRoutes();

    foreach ($routes as $route) {
        $data[] = [
            'pattern' => $route->getPattern(),
            'methods' => $route->getMethods(),
            'middleware' => !empty($route->getMiddleware()),
            'callable' => $route->getCallable()
        ];
    }
    $body->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));

    return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withBody($body);
});

Example output:

 {
        "pattern": "/withmiddlware",
        "methods": [
            "GET"
        ],
        "middleware": true,
        "callable": "App\\Action\\HomeIndexAction"
    },
    {
        "pattern": "/route",
        "methods": [
            "GET",
            "POST"
        ],
        "middleware": false,
        "callable": {}
    }

#7

Yes you’re right but I can’t make the condition with use bool only, I need the middleware name to make sure the array list is acurate.


#8

Okay, but closures (callbacks) are anonymous functions with no names.
Also note that in Slim you can also add middleware to a routing group.


#9

that is why is the static array generic option and will work also for this closures - but you need to add “middleware usage” in each of this function manually :wink: