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

Subcontroller

Hello!

I'm starting to program my project Phalcon, but I have a problem ... I need to use subcontrollers, I have proven the simple-subcontroller, but does not work when I try to access to the sub.

(The simple-subcontroller code has not been modified from the original)

https://ekitea.com/simple-subcontrollers/users https://ekitea.com/simple-subcontrollers/admin/users

Best regards, Cristian

Hi,

First question - do you use namespaces in your project?

Yes... the project only contains de simple-subcontrollers code, it's possible work with subcontrollers without namespaces??

Thanks, Cristian



5.2k
Accepted
answer

Hmm, I never try without namespaces because this is a good practice.

There are a few things which you must do it to subcontrollers works.

Erorrs * handler class cannot be loaded means that you don't tell phalcon where can find your class.

You must register namespace in \Phalcon\Loader(). If you using one of default project architecture the loader should be in app/config/loader.php. Open this file and fill like this:

$loader = new Phalcon\Loader();

 //Register some namespaces
 $loader->registerNamespaces(array(
   'MyApp\Controllers\Admin\' => __DIR__ . '/../controllers/admin/', // this should be a path do your subcontroller dir
 ));

 //register autoloader
 $loader->register();

You should create also a custom router. Create a file router.php in app/config/router.php with content like this:

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

// Route for dashboard/homepage
$router->add("/[/]?", array(
    'namespace' => 'MyApp\Controllers\\',
    'controller' => 'index',
    'action' => 'index',
));

// Route for default controller action
$router->add("/:controller[/]?", array(
    'namespace' => 'MyApp\Controllers\\',
    'controller' => 1,
    'action' => 'index',
));

// Route for controller action
$router->add("/:controller/:action[/]?", array(
    'namespace' => 'MyApp\Controllers\\',
    'controller' => 1,
    'action' => 2,
));

// Route for controller action params
$router->add("/:controller/:action/:params[/]?", array(
    'namespace' => 'MyApp\Controllers\\',
    'controller' => 1,
    'action' => 2,
    'params' => 3,
));

$router->add("/admin[/]?", array(
    'namespace' => 'MyApp\Controllers\Admin\\',
    'controller' => 'index',
    'action' => 'index',
));

// Route for default controller action
$router->add("/:controller[/]?", array(
    'namespace' => 'MyApp\Controllers\Admin\\',
    'controller' => 1,
    'action' => 'index',
));

// Route for controller action
$router->add("/:controller/:action[/]?", array(
    'namespace' => 'MyApp\Controllers\Admin\\',
    'controller' => 1,
    'action' => 2,
));

// Route for controller action params
$router->add("/:controller/:action/:params[/]?", array(
    'namespace' => 'MyApp\Controllers\Admin\\',
    'controller' => 1,
    'action' => 2,
    'params' => 3,
));

Next open your app/config/services.php and add:

//Registering a router
$di->set('router', function() {
    if (!file_exists(__DIR__ . '/router.php')) {
        throw new \Exception('Router file does not exists!');
    }
    require_once __DIR__ . '/router.php';
    return $router;
});

Now should be works



959
Accepted
answer
edited Jun '14

Hi Macin!

Thanks you very much!

The only thing I had to change about your instructions has been this (in loader.php):

$loader->registerNamespaces(array( 'MyApp\Controllers' => DIR . '/../controllers/', 'MyApp\Controllers\Admin' => DIR . '/../controllers/admin' ))->register();

It is best to use this?:

$loader = new \Phalcon\Loader();

Instead of this?

$loader = new Phalcon\Loader();

edited Jun '14

Hi,

There is no difference between use \Phalcon\Loader; and Phalcon\Loader; if you have code like this:

namespace MyApp\Something;

use Phalcon\Loader;

///class definition here...

But If you use namespaces inside of class imagine that namespace is a file path. The first namespace (\Phalcon\Loader) has a absolute path, the second (Phalcon\Loader) has a relative path.

namespace MyApp\Something;

class Example 
{
    public function someMethod()
    {
        return new Phalcon\Loader();
    }

    public function anotherMethod()
    {
        return new \Phalcon\Loader();
    }
}

The someMethod() return error:

Fatal error: Call to undefined function MyApp\Something\Phalcon\Loader()

The anotherMethod will be works.

Ohhh!!

Great example, really thanks ;-)

Best regards, Cristian

edited Jun '14

Hi again!!

I'm trying to add a 404 page... with the same code...

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

$router->notFound(array( 'namespace' => 'MyApp\Controllers\', 'controller' => 'error', 'action' => 'show404' ));

// Route for dashboard/homepage $router->add('/[/]?', array( 'namespace' => 'MyApp\Controllers\', 'controller' => 'index', 'action' => 'index', )); ...

And I have anew controller, bot doesn't work :S

<?php namespace MyApp\Controllers; class ErrorController extends \Phalcon\Mvc\Controller {

public function show404Action()
{
  echo 404;
  exit;
}

}

You can help me? Thanks

Best regards, Cristian