Search code examples
phpurl-routingslim

How to dynamically call methods with slim router?


I'm setting up slim router v4, and I'd like to be be able to dynamically call the controller methods, using the placeholder from the route.

I.e when a request is made to 'example.com/users/{action}', the router would call the method from Users.php controller automatically without me having to specify the routes manually.

Basically I'm trying to avoid manually adding over 100 group->get(...) when they're all under /user route.

namespace core\router;
use Slim\Interfaces\RouteCollectorProxyInterface;
use app\controllers\users;

$app->group('/user', function(RouteCollectorProxyInterface $group){
  $group->get('/get-name', '\Users:name')
  $group->get('/get-personality', '\Users:personality');
});

Further explanation is provided here but I'm not sure how to go about this.


Solution

  • The way I would suggest doing this is having a single, catch all route with a placeholder. You can then set action to an invocable controller, and execute a method based on the route parameter.

    Route:

    $app->get('/user/{method}', Users::class);
    

    Controller

    class Users
    {
        public function __invoke(Request $request, Response $response, $args)
        {
            if (empty($args['method'])) {
                throw new InvalidArgumentException();
            }
    
            $methodName = toCamelCase($args['method']);
    
            if (!method_exists($this, $methodName)) {
                throw new InvalidArgumentException();
            }
    
            return $this->{$methodName};
        }
    
        public function getName(Request $request, Response $response)
        {
            // ...
        }
    
        public function getPersonality(Request $request, Response $response)
        {
            // ...
        }
    }