Skip to content

Instantly share code, notes, and snippets.

@igorw
Last active December 11, 2015 12:28
Show Gist options
  • Save igorw/4600419 to your computer and use it in GitHub Desktop.
Save igorw/4600419 to your computer and use it in GitHub Desktop.
Comments: Autoload path depth insanity

Comments: Autoload path depth insanity

Please leave your comments for the Autoload path depth insanity blog post on this gist.

Any type of feedback is welcome. Including alternate suggestions, corrections, insults, etc. Thanks!

P.S.: I apologize for the crappy format. I will try go get a better way to post comments soon, promise!

@igorpan
Copy link

igorpan commented Jan 23, 2013

I absolutely agree. Few days ago I was starting a really simple library and, being new to composer, spent some time finding a way to make autoloader work. I was amazed when I found out that there is no way to just add a "class prefix" as you call it. So my really small "library" ended up having more folders than files.

P.S. That comic made me laugh really hard!

@tPl0ch
Copy link

tPl0ch commented Jan 23, 2013

Concerning the separation of Unit, Functional and Integration tests: You can additionally use the @group annotation to seperate the test cases so that a CI server would be able to run all, or only unit tests, or functional and integration tests.

@edorian
Copy link

edorian commented Jan 23, 2013

I'm not a big fan of using @group for unit/ functional/ foo/ bar/ seperation for a couple of reasons.

For one i want the folder structure anyways as it allows me to also add behat, javascript and other stuff in a way i perceive as clean. Apart from that I don't like having to remember to annotate every test with a group annotation (It's not that hard to build a phpcs sniff for that, true) but since @group works on the class doc block it's not that much of an hassle.

I like the folder separation better because I've, personally, had better experiences when using that style but all in all it's a rather minor point anyways :)

@simensen
Copy link

If the end result is that the Composer autoloader would get a full prefix map (similar to what it does with target-dir) all the better. :) (It enables things like PSR-0 Resource Locator to be able to find resources (non-classes) based on the same rules as finding classes.)

I mentioned before that I feel like this should be treated as an extension of PSR-0 rather than something new. I think if you ever approach FIG about this you might get better mileage that way. (I could be wrong on that)

Symfony Bundles are already doing something like this and, as far as Composer is concerned, those packages are still listed as PSR-0. The only difference here, from my perspective, is that "src" is defined rather than being "". The rule here for Composer would be:

"if a target-dir is specified, and the PSR-0 autoloader value is not empty, remap the code from the autoloader value ("src") instead of remapping the entire project root ("")."

I realize that this won't work currently. But with a little work I think that Composer could be updated to make the following work as you want:

{
    "autoload": {
        "psr-0": { "Igorw\\Ilias": "src" }
    }.
    "target-dir": "Igorw/Ilias"
}

If psr-n ever gets pushed through FIG, people could continue to use their "psr-n" based projects in the above format or (after Composer is updated) they could start to migrate them to the less verbose syntax:

{
    "autoload": {
        "psr-17": { "Igorw\\Ilias": "src" }
    }
}

@till
Copy link

till commented Jan 27, 2013

Have you considered using a psr-0 autoloader (in composer) during dev? Then you don't need to regenerate the classmap constantly. Should solve this issue.

@lsmith77
Copy link

Its not ideal, but its also not a pain point for me. So in the grand scheme of things I prefer keeping the standard simple.

@schmittjoh
Copy link

imo this is not only a problem with auto-loading, but also with the one class per file approach.

I think PHP should consider adding support for embedded classes:

class Foo
{
    class SomeExceptionOnlyFooThrows extends \Exception { }
    interface SomeInterfaceThatOnlyFooUses { }
    // etc.
}

and also anonymous classes

interface Foo { function foo(); }

new Foo {
   public function foo() { }
}

that would allow us to remove a lot of files from those directories.

@beberlei
Copy link

@schmittjoh you are completely changing the topic.Not Sure that helps

@igorw I am against this, i think the greatest benefit of PSR-0 is the file <-> class mapping, which allows easy traversal of libraries even if you don't know them.

@schmittjoh
Copy link

@beberlei, if I read igor's post correctly, then verbosity was one of the concerns, and I agree with that. However, less files would also mean less verbosity/directories/depth, just that it would not be achieved via a class prefix (stripping off some parent directories), but more horizontally.

@JimPanic
Copy link

+1 to that, I really hate all that nonsensical directory noise.

@dlsniper
Copy link

Like @beberlei said, having the namespaces mapped to directory makes it very simple to navigate to what you need to find.

Now, the 'problem' is that Composer adds some extra vendors/vendor/something over the library which indeed is not nice to the filesystem nor to navigation, I guess that one should rather fix this in some way if such exists.

It's true that my IDE does all the hardwork for me and sends me to the right file/directory every time it's also true the that the whole navigation issue, from PHP pov is fixed when you enable apc.stat = 0.

From my recent testing, it also proves that large classmaps, such as a Symfony2 project are rather problematic even for pretty decent computers. You can view the results here. (note: if you can run the same kind of tests, please do so, it would really help).

@igorw
Copy link
Author

igorw commented Jan 27, 2013

Just before this discussion starts focusing too much on composer: I don't think the files in vendor are that big a problem, since you don't interact with them often. The actual code of the package it is way more relevant imo.

@kastaneda
Copy link

I agree completely on this proposal. I hate pointless directories like src/CompanyName/ProjectName, especially when there is only one CompanyName inside src and only one ProjectName in CompanyName. And this crap inside every module / bundle! We should stop this madness.

@lanthaler
Copy link

I have to admit I don't fully understand the problem. You say you don't care about the directory structure in vendor because "you don't interact with them often". So why is it a problem in your project then? The class_prefix you propose can already be emulated by composer if I'm not completely wrong. Look for example at this library: https://github.com/lanthaler/JsonLD. There are no unnecessary directories at all since composer has been told that the root dir represents ML\JsonLD:

   ...
    "autoload": {
        "psr-0": { "ML\\JsonLD": "" }
    },
   ...

@simensen
Copy link

@lanthaler I think that the idea here is that @igorw would still like the flexibility to have the source be under src/ and not force everything to be in the root of the repository.

@igorw
Copy link
Author

igorw commented Jan 28, 2013

@lanthaler you are mistaken, and this is in fact covered in the FAQ in the blog post. The JsonLD library has the source code at the root of the project and uses target-dir. The reason I do not want that is because I prefer a top-level separation between source code, tests and other resources like documentation. For this reason, I want a src directory at the top level.

My proposal would be able to replace target-dir. But target-dir is not able to support my use case.

@Seldaek
Copy link

Seldaek commented Jan 29, 2013

FWIW, I agree. It would be a small improvement.

On the other hand, I think PSR-0 has bigger issues, namely I'd like to be able to separate classes on the file system for logical grouping while browsing, but still have them in the same namespace because they belong together and that would reduce use-hell.

For example, all the Exception subnamespaces make no sense IMO. Why should I use Vendor\MyLib\Exception\FooBarException; from Vendor\MyLib\Logic? Simply throwing FooBarException would be easier, but if I want to stow away my exception classes under a subdir to avoid cruft in the main one, I have to use a different namespace.

Obviously this would be a broader divergeance from PSR-0, and I am not sure if there is a way to define rules to allow this to work as I want without allowing a mess to emerge. Obviously I could already use classmap right now to do this, but as @igorw pointed out, that has drawbacks too. Anyway just throwing this out here, in case someone else has an idea.

@Crell
Copy link

Crell commented Feb 10, 2013

A number of people have raised a similar issue in Drupal as we've been pulling in more and more 3rd party libraries. I like this idea overall. Please do submit it to FIG for discussion. :-)

@AmyStephen
Copy link

I am so glad to see this raised @igorw Earlier today, I made a suggestion in the PSR forum regarding this issue.

My suggestion is simple. No programming changes. No standards changes. Just a change in the practice of how these package repositories are created.

If we use a folder structure for the packages (components), like this:

http://s7.postimage.org/7ar0rbvmz/Screen_shot_2013_02_10_at_9_04_50_AM.png

And, use class maps for unit testing, Composer and Packagist install the package neatly under the Vendor folder and there is only one occurrence (not two) of the Vendor/Package layer.

I posted my question https://groups.google.com/forum/#!topic/php-fig/-BPdegzme_Y - although I should have been more clear -- the discussion seems to be heading into areas other than this double layers of the Vendor/Package issue.

Would using the directory structure pictured above for packages be a reasonable solution?

@AmyStephen
Copy link

@Seldaek - the issues you are raising are important, in fact, it leads into best practices for overrides. As a separate discussion, It would be good to see your topic further discussed, as well.

@erikaheidi
Copy link

Well, I don't have much to add in this discussion, just would like to say that I honestly like the idea and Im sure this would have helped me when I first started to work with psr-0 autoload. I remember very well how I hated the folder verbosity when I realised that I NEEDED to use this crazy structure, even for something very simple. [+1]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment