We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Best way to check if a controller exists in a custom route matching

Hi guys,

I want to achieve the following behaviour:

  • Use the default configuration of Phalcon router
  • Allow custom routes to be set in the database
  • Custom routes and the default route can have the same pattern (conflict)
  • Custom routes set in the database can't match a controller name (to avoid conflict)
  • Default routes have priority

I want it to be as performant as possible since almost all hits will pass through this route. I want to avoid unecessary filesystem checks and database trips. I was looking for a method within Phalcon to check if a controller exists, but I couldn't find one so I decided to use is_file.

Here is my implementation. If the route matches an existing controller, I simply fail the route and let Phalcon use the default route resolution. If a controller doesn't exist then I redirect to a custom controller (Profile) that will eventually check if the route is set in the database.

$router->add('/([a-z\d.]{6,})/:params', [
    "controller" => "profile",
    "action" => "index",
    "username" => 1,
    "params" => 2
])->beforeMatch(function($uri, $route) use ($di) {
    if (preg_match($route->getCompiledPattern(), $uri, $match)){
        $username = $match[1];
        $controller = ucfirst(strtolower($username));

        if(is_file($di['config']->application->controllersDir . $controller . 'Controller.php')){
            return false;
        }
    }

    return true;
});

Any thoughts? Suggestions?



17.5k

My first quesetion is if you're looking for performance, why are you handling routes through a database? That seems counter-productive. If you're looking for performance there wouldn't be any routing handled outside of Phalcon, or whatever framework you're using. Yes, the models would access your database and if that's what you're talking about then I think its "easier" to create all custom routes and then tweak for performance from there. That's what I'm doing, anyway... No need to make your app way more complicated than it needs to be for what might be not much of a performance increase.