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

Routing collisions

I am trying to setup a router which recognizes controllers and actions automatically but uses different namespaces for frontend and backend.

For instance /some/stuff should be recognized as \Mysite\Mvc\Controller\Frontend\SomeController::stuffAction, when /backend/dashboard/analytics should be recognized as \Mysite\Mvc\Controller\Backend\DashboardController::analyticsAction.

Looks like it works properly right now, but there is one issue when I enter /backend/ url, it doesn't recognize as \Mysite\Mvc\Controller\Backend\IndexController::indexAction, it is recognized as \Mysite\Mvc\Controller\Frontend\BackendController::indexAction. What am I doing wrong?

Here is my router setup stuff:

    $backend = new \Phalcon\Mvc\Router\Group( array( 'namespace' => 'Mysite\Mvc\Controller\Backend' ) );
    $backend->setPrefix( '/backend' );
    $backend->add( '/:controller/:action/:params', array( 'controller' => 1, 'action' => 2, 'params' => 3 ) );
    $backend->add( '/:controller/:action', array( 'controller' => 1, 'action' => 2 ) );
    $backend->add( '/:controller', array( 'controller' => 1, 'action' => 'index' ) );
    $backend->add( '/', array( 'controller' => 'index', 'action' => 'index' ) );

    $router = new \Phalcon\Mvc\Router();

    $router->removeExtraSlashes( true );
    $router->setDefaultNamespace( 'Mysite\Mvc\Controller\Frontend' );
    $router->setUriSource( \Phalcon\Mvc\Router::URI_SOURCE_SERVER_REQUEST_URI );
    $router->notFound( array( 'controller' => 'index', 'action' => 'route404' ) );

    $router->mount( $backend );
    $router->add( '/:controller/:action/:params', array( 'controller' => 1, 'action' => 2, 'params' => 3 ) );
    $router->add( '/:controller/:action', array( 'controller' => 1, 'action' => 2 ) );
    $router->add( '/:controller', array( 'controller' => 1, 'action' => 'index' ) );
    $router->add( '/', array( 'controller' => 'index', 'action' => 'index' ) );

    return $router;

P.S.: I don't want to use modules.

Why don't you want to use modules? This is exactly what modules are for. It may take some reworking, but it's always a best practice to use technology as it's intended, rather than trying to shoehorn different functionality in.

edited Jun '14

Ok, I have reworked my site to work with modules, but there is the same issue: it doesn't recognize default controller for backend module. Here is my router:

$router = new Router();

$router->setDefaultModule( 'frontend' );
$router->setDefaultNamespace( 'Mysite\Frontend\Controllers' );
$router->setUriSource( Router::URI_SOURCE_SERVER_REQUEST_URI );
$router->removeExtraSlashes( true );

$backend = new RouterGroup( array(
    'module'     => 'backend',
    'controller' => 'index',
    'namespace'  => 'Mysite\Backend\Controllers',
) );
$backend->setPrefix( '/backend' );
$backend->add( '/:controller/:action/:params', array( 'controller' => 1, 'action' => 2, 'params' => 3 ) );
$backend->add( '/:controller/:action', array( 'controller' => 1, 'action' => 2 ) );
$backend->add( '/:controller', array( 'controller' => 1, 'action' => 'index' ) );

$router->mount( $backend );

return $router;

When I am viewing /backend/index/index or /backend/index, it is recognized properly and backend index controller is used, but when I am viewing /backend page, I see an error that frontned BackendController is not found. What I am doing wrong?



6.2k
Accepted
answer

Ok, I have figured out that I need to add empty pattern to $backend group, like this:

$backend->add( '', array( 'controller' => 'index', 'action' => 'index' ) );