3
votes

I am currently running Slim and Twig, my folder structure is as follow

/application/modules

In my composer.json I have

"autoload": {
    "psr-4": {
        "Application\\":        "application/modules/",
        "Core\\":               "application/",
        "Middleware\\":         "application/slim/middleware/"
    }
}

My issue is is that in Application\modules\ I have a directory for each module. Now my question is, is it possible to make composer iterate through the sub directories when using PSR-4 autoload?

1
I believe explicit declaration is required for PSR-4.Ohgodwhy
I thought as much, however I hoped there would be a way of doing itIan
I'm going to watch this question because I'm interested as well. I've encountered this issue before and I never found a way around it.Ohgodwhy
Once you have a namespace prefix defined, every sub-directory maps one to one with additional namespaces in a case sensitive fashion. So Application\foo\Bar will look at application/modules/foo/Bar.php. I get tripped up so often by this I decided I'd finally commit it to memory by writing it down!bishop

1 Answers

3
votes

I see an issue with your PSR-4 declaration.

You shouldn't place "Core" classes inside a folder that has subfolders for other namespaces.

PSR-4 autoloading in Composer works like this: If the fully qualified class name of the class to load matches a prefix declared in any of the PSR-4 definitions, then the prefix mentioned in the prefix is removed from the class name, and the remaining class name is mapped to a filename and being searched.

If you have classes named Application\ in the folder application/modules, and you have classes named Core\ in the folder application, then technically Composer might find files that match a class name like Core\modules\Whatever, although these file will contain a class Application\Whatever instead.

I recommend moving all the Core classes into their own folder and point to this in the PSR-4 declaration.

The problem with your original question is that you omit an important information: What is the class and file structure for your modules?

Composer's autoloader will happily resolve any class that starts with the namespace prefix Application, remove that prefix from the classname, convert the remainders into a path name and search for that file in application/modules/. Given that you have a module class Application\MyModule\Foobar, it will be searched in application/modules/MyModule/Foobar.php. Why? Because the prefix Application will be removed to allow for shorter path names in PSR-4. (Using PSR-0 would mean you have to have a folder for every level of namespace in the classname.)

Note that it is recommended for optimum performance to make the prefix for namespaces as long as possible, because Composer allows to have more than one directory for any given prefix, but then has to search for the correct file in more than one directory. Searching for files is time consuming!