Getting controller/action name in beforeMatch for routing

I'm trying to simplify a routing scheme to only make a generic route handle many cases. I have the following code:

    // Routes must be in the format `/api/<controller>/ajax-<action>`
    // Example: `/api/purchase/ajax-add-value` maps to `PurchaseController::ajaxAddValueAction`
    $router->add('/api/([a-z-]+)/(ajax-[a-z0-9-]+)', [
        'controller' => 1,
        'action' => 2,
    ])->convert('controller', function($controller) {
        return Text::camelize($controller);
    })->convert('action', function($action) {
        return lcfirst(Text::camelize($action));
    });

This is working great for the controllers/actions that exist. However, when something matches the pattern that doesn't exist, it's throwing a 503. I was wondering if there was something I can chain to this to make the route not match if the controller/action does not exist. I tried to toy around with $route->beforeMatch() , but was unsuccessful at getting the controller and action name. Any advice here would be appreciated.

An example invalid route would be: /api/foo/ajax-bar

I did see this similar unresolved discussion: https://forum.phalconphp.com/discussion/7367/best-way-to-check-if-a-controller-exists-in-a-custom-route-match



3.2k

This is usually passed off to the the Dispatcher. You can use these inside the handler to get controllers, actions:

$controller = $dispatcher->getControllerName();

$action = $dispatcher->getActionName();

Here is an example to handle bad routes from my services.php:

$di->set('dispatcher', function() {

    // Create an EventsManager
    $eventsManager = new Phalcon\Events\Manager();

    // Attach a listener
    $eventsManager->attach('dispatch:beforeException', function($event, $dispatcher, $exception) {

        // handle exceptions
        switch($exception->getCode()) {

            case Phalcon\Mvc\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
            case Phalcon\Mvc\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
                // forward to 404 page
                $dispatcher->forward([
                    'controller' => 'error404',
                    'action' => 'index'
                ]);
                return false;
        }
    });

    $dispatcher = new Phalcon\Mvc\Dispatcher();

    // Bind the EventsManager to the dispatcher
    $dispatcher->setEventsManager($eventsManager);

    return $dispatcher;

}, true);