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

How does router work?

Hello, I'm trying to use the router with groups. These are my directories:

/app
    /config
        /routes
            IndexRoutes.php
            UserRoutes.php
        router.php
        services.php
    /controllers
        /index
            ControllerBase.php
            IndexController.php
        /user
            ControllerBase.php
            IndexController.php

Before explain my issue, I'll show you the content of these files.

services.php:

$di->set('router',function(){
    return require __DIR__ . '/router.php';
},true);

router.php:

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

// Default routes
$index = new Config\Route\IndexRoutes();

$router->mount($index);

// User routes
$user = new Config\Route\UserRoutes();
$router->mount($user);

return $router;

IndexRoutes:

namespace Config\Route;

use Phalcon\Mvc\Router\Group;

class IndexRoutes extends Group{

  public function initialize(){

      $this->add('/:controller/:action/:params',array(
          'controller'=>1,
          'action'=>2,
          'params'=>3
      ));

      $this->add('/:controller',array(
          'controller'=>1
      ));

      $this->add('/:controller/:action',array(
          'controller'=>1,
          'action'=>2
      ));

      $this->add('/', array(
          'namespace'=> 'Test\Controllers\Index',
          'controller' => 'index',
          'action' => 'index'
      ));
  }

}

UserRoutes.php:

namespace Config\Route;

use Phalcon\Mvc\Router\Group;

class UserRoutes extends Group{

    public function initialize(){

        $this->setPrefix('/user');

        $this->add('/:controller/:action/:params',array(
            'controller'=>1,
            'action'=>2,
            'params'=>3
        ));

        $this->add('/:controller',array(
            'controller'=>1
        ));

        $this->add('/',array(
            'namespace'=>'Test\Controllers\User',
            'controller'=>'index',
            'action'=>'index'
        ));

    }

IndexController:

<?php

namespace Test\Controllers\Index;

use Phalcon\Http\Response;
use Phalcon\Logger\Formatter\Json;
use Test\Model\IndexModel;

class IndexController extends ControllerBase
{

    public function indexAction()
    {
        $this->view->disable();

        $arr = $this->router->getActionName();

        echo $arr;

}

And now, I want see, what router works. And how does router work?

In tutorial writed, if loader register namespaces, class in this namespace be loaded.

In tutorial was written, if loader register namespaces, class in this namespace will be loaded. It works only for built-in classes/actions?

But if I remove this, from dispatcher:

$dispatcher->setDefaultNamespace('Test\Controllers\Index');

I think what router doesn't work.

And I get this Exception:

Phalcon\Mvc\Dispatcher\Exception: IndexController handler class cannot be loaded

How Router and Dispatcher work together? Did I miss something.

Thanks



10.0k
Accepted
answer
edited Jul '14

Wonderful! Wow! Super behavior.

If default routes are off.

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

Without $router->setDefaultNamespace('') didn't work. even If you add a namespace to the Group of Routes.

Thanks :)

Here is my router service:

$di->setShared('router',
  function () {
    $router = new Router(FALSE);

    $router->notFound(
      [
        'namespace' => 'MyApp\Controller',
        "controller" => "error",
        "action" => "show404"
      ]
    );

    $router->mount(new Route\IndexGroup());
    $router->mount(new Route\ErrorGroup());

    return $router;
  }
);

And my group class:

class IndexGroup extends Group {

  public function initialize() {
    // Sets the default controller for the following routes.
    $this->setPaths(
      [
        'namespace' => 'MyApp\Controller',
        'controller' => 'index'
      ]);

    $this->addGet('/', ['action' => 'index']);

    $this->addGet('/tour/', ['action' => 'tour']);
    $this->addGet('/contacts/', ['action' => 'contacts']);

    // All the following routes start with /aggiornamenti.
    $this->setPrefix('/updates');

    $this->addGet('/newest/', ['action' => 'newest']);
    $this->addGet('/popular/{period}', ['action' => 'popular']);
  }

}

Every route needs: the controllers namespace, controller name, action name.