Namespace order

What order for namespaces is correct?

$loader = new Phalcon\Loader();
$loader->registerNamespaces(
  [
    'App\\Frontend' => '/../app/frontend',
    'App\\Frontend\\Controllers' => '/../app/frontend/controllers',
  ]
);
$loader->register();

or: ```php $loader = new Phalcon\Loader(); $loader->registerNamespaces( [ 'App\Frontend\Controllers' => '/../app/frontend/controllers', 'App\Frontend' => '/../app/frontend', ] ); $loader->register(); ```

UPD: the number of registered namespaces affect performance? For example, if i register all available namespaces in one place this not decrease performance?



81.8k

Basically, if you have the following namespace/location registered:

'App\Frontend' => '../app/frontend/'

the process made by the auto-loader if the class to load is App\Frontend\Controllers\MyController is:

1) Traverse all the registered namespaces 2) Check if the class name to load start with one of the registered namespace prefixes 3) If a prefix is found then the prefix is removed from the beginning of the string, in our case: App\Frontend\Controllers\MyController - App\Frontend = Controllers\MyController 4) The path related to the prefix is prepended to the string generated in step 3 plus the .php extension resulting in '../app/frontend/' + Controllers/MyController + .php = '../app/frontend/Controllers/MyController.php 5) The auto-loader checks if this file exists, if yes, the file is required, otherwise try with another prefix

As seen above, the path contains the "Controllers" word with the first letter as it is in the class name, if a developer wants another name, for example: "controllers" in lowercase, it's necessary register a specific path for it: 'App\Frontend\Controllers' => '../app/frontend/controllers/'.

The idea behind using this auto-loader is reduce the number of stats performed in each request, a higher number of prefixes registered don't affect performance, but a high number of stats made (access the filesystem) lead to a bad performance. According to the steps mentioned above, just one stat was performed which is good.

Hmmm, registering only top level of namespace does not work. When i'm try set default dispatcher namespace to 'App\Frontend\Controllers' it's throw exception like 'App\Frontend\Controllers\IndexController handler class cannot be loaded' upd: all files exists and work nice when i'm register nested namespaces



81.8k

I think the problem is the slash at the beginning of the path: '/../app/frontend/controllers'

No, slash is not problem. These are the paths which I'm trying to use: ```php 'App\Frontend' => '../app/frontend' ``` and ```php 'App\Frontend' => '/home/mitris/www/framework/app/frontend' ``` Paths with a slash at the end also does not have effect

In all examples you manually registered a namespace for controllers. in my situation event listener told me that load this path like /home/mitris/www/framework/app/frontend/Controllers/IndexController.php thanks, but I'm not fully understand why loader camelizes only controller dir. so if i auto load app dir like 'App' => '../app', autoloader try find controller in ../app/Frontend/Controllers dir?



81.8k

The loader does not camelize the directories, they're used as they come in the class name:

If the class is App\Frontend\Controllers\MyController it just remove the prefix and add ".php": ../app/Frontend\Controllers\MyController.php

When I'm simply registering 'App' namespace which contain 'Frontend/Controlles' folder it's working too. Is it normal to register a top level namespace? Or is better register App\Frontend and App\Backend separately?



81.8k

You can register a top level namespace, but only if you're comfortable with directories as they're in the class names

Is it possible to enable (or implement) camelization for the directories names?

Here is a simple way to split frontend and backend in Phalcon project without modules: https://github.com/borzov/phalcon-templates

I use it on small projects. Maybe it will help you.

edited Apr '14

I was having a problem with loading the ControllerBase and the rest of the controllers in the controllers folder using namespaces. I was having a hard time since other example projects worked fine and I realized that i was missing a small detail in the despatcher declaration where I was supposed to setDefaultNamespace

(ref: https://github.com/phalcon/vokuro/blob/master/app/config/services.php)

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

$dispatcher = new Dispatcher();

$dispatcher->setDefaultNamespace('Vokuro\Controllers');

return $dispatcher;

});

after that it worked fine, even though it shouldn't be like that since namespaces are registered in the loader file anyhow, I hope it helps, good luck



98
edited May '14

Thanks a lot, Avenir