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

Nested Multi Module setup loader configuration

Hello there,

English is not my first language and my problem is too complex to translate it in clear english. Thanks you for patience.

I'm trying to setup Phalcon for my next project setup. Due to our projects nature I have a relatively complex project layout. In my project, I had unlimited multimodule apps.

It was something like.

/app
/app/app1/modules/modules1/controllers
/app/app1/modules/modules2/controllers
/app/app2/modules/modules1/controllers
etc

To manage routing and loading I have a small router code which works before Phalcon config. I get current app, module, controller, action and parameters from the URL then modify the Phalcon config. So I reach the multi app with multi module setup.

My Old Setup config

'dirs' => array(
        'appDir'         => preRouter::$appDir,
        'moduleDir'      => preRouter::$moduleDir,
        'controllersDir' => preRouter::$moduleDir.'controller'._DS_,
        'libraryDir'     => SYS_DIR.'library'._DS_,
    ),
    'prefix'=> array(
        'service_'=> SYS_DIR.'service'._DS_,
        'repository_'=> SYS_DIR.'repository'._DS_,
        'form_'=> SYS_DIR.'form'._DS_,
        'model_'=> SYS_DIR.'model'._DS_,
        'task_'=> SYS_DIR.'task'._DS_,
        'daemon_'=> SYS_DIR.'daemon'._DS_,
    ),

However this config based on register dirs which costs lots of file search.

I want to move my structure from $loader->registerDirs to $loader->registerPrefixes

My attempts to archieve this have failed. I can manually load the controller class however dispatcher cannot load it.

/var/www/orkun/app/admin/default/controller/IndexController.php 
/var/www/orkun/app/admin/default/base.php 
/var/www/orkun/app/admin/base.php 
/var/www/orkun/app/base.php 
IndexController handler class cannot be loaded
#0 [internal function]: Phalcon\Mvc\Dispatcher->_throwDispatchException('IndexController...', 2)
#1 /var/www/orkun/pub/index.php(146): Phalcon\Dispatcher->dispatch()
#2 {main}

My New Setup Config

    'prefix'=> array(
        'app_'=> APP_DIR,
        'lib_'=> LIB_DIR,
    ),

Is there any $dispatcher example based on registerPrefxes.

My Best Regards



7.9k

You can use PSR-4 autoloading standard it make life easier.

$loader->registerNamespaces( [ "vendor\package" => DIR . "/../app" ], true )->register();

It will autoload all folder including subfolder (as long as you follow PSR4 autoload standard)



11.9k
Accepted
answer
edited Nov '14

My solution was.

1-) Have pre-router to determine current application and module.

2-) Make a dynamic controller path for loader.

3-) Other classes can use Prefixed loader config except models.

4-) Models must use namespaces.

Final solution.

<?php

return new \Phalcon\Config(array(
    'database' => array(
        'adapter'     => 'Mysql',
        'host'        => 'localhost',
        'username'    => 'root',
        'password'    => '1234',
        'dbname'      => 'a_seller',
    ),
    'dirs' => array(
        'controllersDir' => preRouter::$moduleDir . 'controller' . _DS_,
    ),
    'prefix'=> array(
        'app_'=> APP_DIR,
        'service_'=> SYS_DIR.'service' . _DS_,
        'repository_'=> SYS_DIR . 'repository'._DS_,
        'form_'=> SYS_DIR . 'form'._DS_,
        'task_'=> SYS_DIR . 'task'._DS_,
        'daemon_'=> SYS_DIR . 'daemon'._DS_,
    ),
    'namespace'=> array(
        'seller\model'=> SYS_DIR.'model'._DS_,
    ),
    'application' => array(
        'cacheDir'       => SYS_DIR.'cache'._DS_,
        'baseUri'        => '/',
        'publicUrl'      => 'seller.int',
        'cryptSalt'      => 'fifif'
    ),
));

$config = include SYS_DIR . "config" . _DS_ . "config.php";

$loader = new \Phalcon\Loader();
$loader->registerDirs(array_values((array)$config->dirs));
$loader->registerPrefixes((array)$config->prefix);
$loader->registerNamespaces((array)$config->namespace);

with this config you can manage nested multi module apps like this

app/app1/modules/module1

app/app1/modules/module2

app/app1/modules/module3

app/app2/modules/module1

app/app3/modules/module1

app/app3/modules/module2

Using register dirs on single directory will prevent source file search on multiple dirs.

My best regards.