Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - PSR-4: Autoloader (composer) and multiple namespaces with the same root

Currently all my classes are in one folder and are under one namespace:

"psr-4": {
   "RootNamespace\\": "lib/"
},

This is working well. As I'm adding more and more classes, I would like to put some logically related classes into deeper namespace level, but with the same root namespace. It should be something like this:

RootNamespace/Services (in 'lib/services' dir)
RootNamespace/Listeners (in 'lib/listeners' dir)

I suppose so that I don't need to change anything in my composer.json ps-4 autoload definition, but it's not working anymore.

How autoload definition should look like to achieve what I want to?

As I tested, solution below is not a good since, declarations seems to be overwritten

"psr-4": {
   "RootNamespace\\": "lib/",
   "RootNamespace\\Services\\": "lib/services/",
   "RootNamespace\\Listeners\\": "lib/listeners/"
},
like image 667
kkochanski Avatar asked Jan 19 '17 21:01

kkochanski


People also ask

What is PSR-4 autoloader for PHP?

It is great idea to create PSR-4 autoloader packages for PHP. PSR describes a specification for autoloading classes from file paths. It is fully inter-operable, and can be used in addition to any other autoloading specification, including PSR-0.

What does PSR mean in composer dump-autoload?

However, if you run the composer dump-autoload command again, the index.php file will work properly. PSR stands for PHP Standard Recommendation. PSR is a PHP specification published by the PHP Framework Interop Group or PHP-FIG.

Is composer affected by autoloading when importing namespaces?

Importing namespaces has nothing to do with autoloading, so Composer is not affected. Importing is like telling PHP "Look, I think there's a class named Foo\Bar, and I will only write Bar in this file" and PHP will expand your Bar to Foo\Bar - and only if this is really used as a class, PHP will trigger the autoloading.

How does composer handle PSR-4 classes?

So all Composer needs to function is a mapping of namespace prefixes to directories. Each library maintains this mapping for its PSR-4-structured classes through the autoload information in their composer.json.


1 Answers

According to the PSR-4 Spec:

All class names MUST be referenced in a case-sensitive fashion.

Your configuration is accurate having different PSR-4 namespaces nested in the same directory. It should work, but may become confusing down the road.

"psr-4": {
    "RootNamespace\\": "lib/",
    "RootNamespace\\Services\\": "lib/services/",
    "RootNamespace\\Listeners\\": "lib/listeners/"
},

I recommend you either simply capitalize your directories to match the PSR spec, or move your RootNamespace out of the top level lib/ directory.

like image 140
Steve Buzonas Avatar answered Sep 27 '22 19:09

Steve Buzonas