I would suggest you define a notFound route at the very bottom of your router:
$router->notFound(['controller'=>'Routing','action'=>'notFound']);
Then you'd define a controller whose sole purpose is to assist with routing within your application.
Define a controller: class RoutingController extends \Phalcon\Mvc\Controller
Then you'd define a notFoundAction
method inside it.
Preform any database queries you need within this controller.
Then decide after these queries where you need to route to.
public function notFoundAction()
{
$url = filter_var(trim(urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)),'/'), FILTER_SANITIZE_URL);
$page = Pages::find($url); // Or whatever you decide to name the model for this
if(!$page){return notFoundPage();} // Display a 404. Avoid usage of exit(), so tests can test this
$namespace = __NAMESPACE__ . '\\';
$controller = $page->controller.'Controller';
$action = $page->action. 'Action';
$parameters= $page->parameters;
return call_user_func_array([$namespace.$controller,$action], $parameters);
}
The next step is defining a Pages model and executing whatever queries you need.
In this manner you'd achieve about as perfect of an architecture that's possible with Phalcon's router.
While it's possible to extend Phalcon's router to execute queries before routing is done, I feel queries should be executed at the controller level, rather than the routing level, then simply hand control over to another controller.
See also: https://docs.phalcon.io/en/3.2/dispatcher
$this->dispatcher->forward( ... )
is probably a cleaner solution.