Is PSR-0 Shortsighted, or are you?

Posted: 2013-04-17
Category: PHP

One of the fun things about trying to support the PHP-FIG and all the good its doing, is seeing blog posts written complaining about it by people that just don't know what they're talking about.

I get involved in conversations on Reddit (dangerous I know) on a mission to understand the problems with its perception throughout the community, and try to make more knowledge readily available to avoid confusion. I put together the PHP-FIG FAQ and the rest of the group voted it in, which I believe helped a lot.

Sadly some blog posts are sent out by people with a whole bunch of odd opinions that you just can't do anything about, so instead I'm going to respond with a play-by-play approach.

Note: I wouldn't have given this the time of day if it weren't for the fact it was linked on some high level PHP sites. Letting odd articles like this circulate without a counterpart is like only letting Republicans on the television. Pretty soon everyone in the world would believe that women had some magical anti-rape-sperm laser hidden away in their vaginas

There's a self-declared PHP "standards" group called PHP-FIG attempting to push several "standards" throughout the PHP community.

Nope.

The problem occurs when PHP-FIG do attempt to push the standard onto everyone else such as trying to put it into the PHP Core…

Back in early 2010 one FIG member made an RFC for this. That was 3 years ago, and this is most likely the only example of the FIG ever trying to push anything on the PHP community as a whole. I think the group realises their mistake, and this is exactly why votes exist on RFCs, to make sure changes are a reflection of what is genuinely good for PHP. It's time we (the internet) let that one go.

…and a lot of campaigning to get people to adopt the "standard".

Where? The FIG is certainly not campaigning to do this. I'm not sure where we'd even do the campaigning. Did you read some blog articles about PHP developers who enjoy using PSR-0 for their packages and assume the FIG had hired them to write the articles? We are the puppet masters.

Even then, I despise the idea of them, or anyone, pushing such a ridiculous "standard" in the first place. My issues are purely practical, PSR-0 reduces flexibility and makes life more difficult for developers. It's self-defeating and as a standard is unfit for purpose. The premise of the standard is: "This is how you must structure your files", which is an absurd starting point.

This seems like the crux of the idea before the author goes on to repeat the same point multiple times. There are two approaches:

A) Define File/Folder Naming Structures

PSR-0 lets you know that you need to use StudlyCaps for your classes and lets you know that _ is a directory separator, that's about it. This means any developer who is building a new package can simply lay out their classes in the specified way, and use any PSR-0 compliant autoloader (of which there are many) to autoload their code.

B) Make an autoloader that can load anything

This is the wild new suggestion that the author is proposing. Well, that sounds quite a lot like Composer. You can take any code, no matter what format, let the author build it however they like, then let all of the code be autoloaded according to the rules the developer has set in the packages composer.json. Is it classmap, or is it PSR-0? Up to them.

Anything else along these lines would be going back a step in logic. If its not classmap, and its not PSR-0, then its fucking magic, exactly what used to happen in the PHP community that we're trying to hard to get away from.

Oh good, Foo {} lives in monkey.class.php, thanks for making that obvious bro.

We shouldn't be defining a standardised autoloader to tell library authors how to do things, instead we should be letting library authors optionally provide a way of telling a standardised autoloader how to load its files.

The FIG is not defining a standardised autoloader, they are standardising the naming conventions that allow for a PSR-0 compatible autoloader. This autoloader is not restricted to JUST PSR-0, they can do what they like.

That autoloader can try loading all of your custom application classes. Drupal and Joomla use their own autoloaders to load some of their own code using whatever the hell rules they see fit, AND ALSO support PSR-0 to load generic code packages, which makes life easier on the package developers because they can just build to PSR-0 instead of building to work with Zend, or work with Drupal, or work with Symfony - exactly the problem we're trying to avoid.

This approach has the added benefit of making it so that older existing libraries can be extended, not altered, to become compliant with the standard. As it stands, to make an existing non-PSR-0 compliant library PSR-0 compliant, the entire library must be restructured, and in a lot of cases, have every single file altered to add a namespace to it! To call this approach absurd would be an understatement.

Restructured how much? Adding in a namespace is not exactly tough, and is part of a reasonable migration to being PHP 5.3 compatable anyway.

Making the class name match the file name? Well that's just good common logic, and if your classes don't match the the file names then why not?

If upgrading this code package is so complicated that it's not worth it, then why are you trying to do it? Includes and classmaps are perfectly valid options unless you're bored and want to take on a random challenge.

Ok, so perhaps we should only use PSR-0 for new projects and new libraries? If you set out to be PSR-0 compliant then you won't have that problem. This is true and exactly why PHP-FIG are pushing/encouraging everyone else to use their standard, but again it's rather backwards. Choosing your autoloader then using that choice to define how your project is structured can very easily result in a project which isn't structured in the best way for that particular project.

Ignoring the fact that the FIG is not pushing/encouraging shit on you, I'm not sure what sort of project would not fit into PSR-0? Are you trying to make your entire application PSR-0, because it should only be generic code packages that you do this with, and I've yet to see a single generic PHP package that would not fit in with PSR-0. If your project is too complicated for PSR-0 (and I'd like to see examples of this so I know what you're actually talking about) then simply don't use PSR-0.

In OOP terms, PSR-0 breaks encapsulation. Code which uses it has implied knowledge about things it shouldn't be concerned with: Directory structures, the implementation details of the autoloader. Storing application configuration along with application logic is a bad idea. It severely limits flexibility by meaning you cannot use different configurations with different logic.

I understand all of the words seperately…

PSR-0 is extremely similar to the PEAR file/class naming structure, but a bit more namespacey. It's also almost identical to the way Kohana, Laravel 3 and FuelPHP do things and almost i-fucking-dentical to Zend.

I have plenty of PSR-0 code which could be autoloaded with a completely custom autoloader, because its just logical naming.

In no way is any "application configuration" stored, inferred or implied by naming your classes and filenames in a logical standard way. You can load this shit with direct includes, and it's all going to work just fine.

As it stands, what actually happens in the real world is that autoloaders are PSR-0 compliant, but then allow a bunch of workarounds to support other non PSR-0 libraries. These workarounds are autoloader specific. Composer uses a classmap, Zend provides several different autoload implementations and Symfony supports PSR-0 as well as a method for loading classes which use the PEAR naming convention.

What this means is that the "standardised autoloader" that PSR-0 advocates, is far from standard unless you limit the flexibility of your projects' structure by using only other libraries which follow PSR-0. As soon as you set foot outside this very narrow scope, you have to configure the autoloader manually.

Right. Absolutely right.

Symfony and Zend both have elements of autoloading that work entirely their own way, and they also support PSR-0 too - which is amazing. Developers can aim at PSR-0 and know their code is going to work everywhere, instead of trying to make it work for each different framework. Yay PSR-0 for making its goal entirely possible!

If the standard defined how autoloaders could be extended, rather than how autoloaders worked, then each library or vendor could provide its own extension to the autoloader.

The PSR-0 standard does not define how autoloaders work. It defines the rules of PSR-0 compatibility, allowing an autoloader to be PSR-0 compatible as well as do whatever else it would like to do, which you've already pointed out is what Zend and Symfony do.

The Example

This is an example of an autoloader implementation. PSR-0 is not an autoloader, it is the standard which defines what rules make something PSR-0 compatible.

There are several things I don't like about this example.

Where does this code live

There is an interface, some rule classes (which constitutes "configuring the autoloader", which the author complained about earlier) and a autoload.json in the "library directory".

Now, what the crap is a .json file doing in my PHP library package?

Go on. Say it. "Composer has a .json file". Right, the .json file and all of this metadata live in the composer package, which just so happens to sit near my PHP code but is nothing to do with PSR-0.

Composer != PSR-0

Almost every time a "PSR-0 sucks" argument comes up its by people that A) do not know that Composer and PSR-0 are not the same thing, or B) do not know that PSR-0 was out for at least a year before Composer was but a twinkle in the eye of Jordi and Nils.

This poster is confusing the fact that PSR-0 is a standard of rules that allow an autoloader to know where stuff is, with Composer which is a dependency manager that can autoload pretty much anything.

That's not the same thing, and I hope you can all see why.

So this is not a PSR-0 competitor

This example is either a replacement for the Composer autoloader, or a potential feature. But even then I have to wonder: is this even anything new?

Why not just auto-include an autoload.php file using the file autoload syntax, then write your custom autoloader in there?

What PSR-0 tries to achieve is good but its execution is one of the most inflexible and restrictive trends to hit PHP for quite some time.

It's 4 years old.

Don't configure your application's structure based on your autoloader, configure your autoloader based on your application's structure.

You really shouldn't be trying to PSR-0 your entire application, that would be suicide.

What's laughable is that over at the PHP-FIG mailing list, there's a post which highlights some of the current implementation restrictions in PSR-0. Their proposed solution? Add another PSR rule as a workaround rather than solving the problem of inflexibility inherent in PSR-0!

There are only two "problems" in PSR-0, neither of which have been touched on in this article.

  1. PSR-0 can autoload two different classes to the same path, then error. I've described it fully here.
  2. PyroCMS has a src/ folder in each module, so some modules PSR-0 folder structure is system/cms/modules/users/src/Pyro/Module/User/Model/Group.php.

So, 1 is fair enough because that was build intentionally, to allow developers to easily support the old underscore structure that people were commonly using, the new autoloader will only work with namespaces to avoid this collision. Nice.

The second point allows the autoloader to allow a little extra config to make it system/cms/modules/users/src/User/Model/Group.php, still mapping to Pyro\Module\User\Model\Group.php, which is trivial at best but will make a few of my module developers happier that they don't need to use those two extra folders. Many projects will definitely still want to use PSR-0, and some will use this new PSR-X, which is nice to have that flexibility.

Composer will then support PSR-X too, so all included packages will automatically be included no matter what PSR they decide to use.

Summary

This article comes across as:

This brand new thing [which is 4 years old] is not exactly what I'd expect to see based on expectations that are being made 4 years after its conception and with the knowledge of tools that didnt exist at the time, and any attempt to improve this situation is laughable because these guys are all tools.

PSR-0 has its problems, but they are the two that I have pointed out and they are rather trivial. These two issues are being removed in a new standard which is currently going through the proposal stages and so far it has excellent support. Once it's voted in and Composer integrates the standard into their autoloader some developers can spend 3 minutes porting their packages, or continue to use PSR-0.

If you'd like to add custom autoloaders to your Composer packages then go ahead. If you'd like to build your own custom autoloaders for all of your packages then you can do that too, but it ruins the entire purpose of what PSR-0 is meant to do.

That's fine, because you don't need to use it, but I am happy as hell that PSR-0 exists and I wouldn't make drastic changes to it for anything. Every developer who chooses to use it (and that is a fucking lot so far) has helped to drastically improve the eco-system of PHP, and thats a trend I like the sound of.

Comments

Gravatar
Michael Wales

2013-04-17

I considered putting my name into the ring, thinking I could contribute the .gov/.mil and "not on the Internet"-network perspective that isn't all too common, but I'm afraid I would have a rant of this nature posted every single day (then I'd be forced to actually get my domain back up and running).

I just don't understand the level of ignorance and blatant "I'm not involved but know more than you" jackassery that is constantly commentating on the FIG's every move. I feel bad for the poor sucker that joins FIG prior to making the conscious decision to become a raging alcoholic like the rest of us.

I'll take a half-sober, fully-not-caring stab at explaining for those that somehow still don't get it. The "Super Happy Unicorn Club" has decided they are going to write all their letters in pink ink and place them in pink envelopes. This way, they'll identify letters to one another more quickly and can do whatever the fuck they want with their <em>own goddamn open source letters</em>. If you don't want to write in pink ink or use pink envelopes, good for you; you weren't invited and no one gives a shit. If you insist on running around behind "Super Happy Unicorn Club" members, whining and crying constantly because their not using the blue envelopes you prefer, or writing in #2 pencils, <strong>fuck you</strong>. You're combatting a misguided notion that someone is forcing you into this new requirement by insisting that they not adopt the requirement they all mutually agreed to...

WTF? This is their party, you're not allowed to tell them Las Vegas is a bad idea; nor can they force you to ease up, have a cold one and stop taking yourself so seriously.

Gravatar
Henry

2013-04-17

I've seen your comments about stuff like this on /r/php. I think it's very valuable to have somebody in that community with some slight name recognition talking sense. /r/php is like an alternate universe sometimes. I often see people there promoting poorly-written but well-marketed libraries, tutorials and blog posts, and it's great to have somebody in there explaining things in an authoritative way without resorting to condescension and rudeness.

Gravatar
Mario

2013-04-17

There's just one tiny thing missing from your PSR-0 FAQ. It bemuses me since inception how insistive people refuse to even footnote that.

The autoloading scheme is quite simple. The shareable loader does the most obvious task. In fact not much thought went into it. Basically class names are just mirrored onto filenames. Just good common logic.

What never occured to our framework pros though is that PHPs class identifiers and the mapped filesystem namespace have different properties. Namely case-sensitivity on *Nix systems and non-case-sensitivity for PHP identifiers. (Opinions may vary, but that's a given). And in practice no big deal, since random capitalization is both odd and uncommon. The also prescribed StudlyCaps scheme is no excuse however for breaking language semantics through the backdoor. (Well, except on Windows filesystems; there it's all correct by accident.)

What's odd here is just that lengthy articles get written about PSR-0 all the time and the however subtle and tiny introduction of language breakage is never ever under no circumstances not mentioned bro.

Gravatar
Norbert Kéri

2013-04-17

The guy managed to attack the one PSR standard, that is the oldest, and most widespread. He would have made much more success if he had poked at PSR1, or PSR2.

Gravatar
Steve Daniels

2013-04-17

You only have to read Tom's About page to get a feel for how all his posts go!

Gravatar
Rob

2013-04-17

While I agree with what you say, I feel it's worth playing devils advocate for a bit, or at least giving the author of the original article the benefit of the doubt.

I think what he's replying to is not posts such as yours which lay out the fundamental basics of PSR-0, but the PSR-0 fanboys (derogatory term intended) who go around on various forums including r/php claiming that PSR-0 is the bees knees. Unfortunately alot of these people don't fully grasp its simplicity and try to make out that it's something it's not i.e. the kind of thing Tom has criticised. These are the kinds of people who think "Phil Sturgeon said it's awesome, so i'll say it's awesome" without looking into it and understanding why it's good. As others have said in these comments, yes it is good to see you around various places speaking common sense, however I often find you're idolised by those who have heard that you speak sense but don't understand the sense that you're actually speaking. Frankly there's as much bullshit said in favour of what you say as there is against what you say and the reason articles like the one you have responded to get shared/upvoted is because alot of the time the arguments are between these two extremes of stupidity. Reddit as a whole, not just r/php, is a haven for that sort of extremism. While i'm grateful for the article and i'll probably have need to link to it at some point i'm afraid by taking the common sense middle ground you're fighting a losing battle as your fanboys and your critics shout misguided obscenities over your head.

(to clarify i'm in no way blaming you for the fanboy attitude that sometimes follows you around, just that I hope you'll agree there's no reason for you or your opinion to be idolised and it's particularly unhelpful when people agree/defend you without actually knowing what you're talking about and wind up constructing a false picture of what you're saying or what PSR-0 is and it is this fanboy constructed false picture that I think Tom has in mind when writing his article, not that, that detracts from its stupidity, since you would have expected that he'd go and read the bloody thing first!)

Gravatar
Anthony Levensalor

2013-04-17

PSR-0 seems the least likely to draw so much contention and ire. It's so simple, so straightforward, and so prima facie _right_ that it defies logic for me to try to fight with something so obvious.

Hell, at the end of the day, I want my projects done, and done as well as possible. I don't want to have to fight about it.

Gravatar
Robert Gentel

2013-04-17

I hate how horribly commonplace it is for folks to fecklessly fucking poke, pick and prod the product of those who have had the temerity to stick their necks out there and actually bloody build something, while themselves contributing not a whit other than their obdurate opinion and strength of conviction.

Gravatar
Zepto

2013-04-17

I agree that the standard is a good thing, and a good direction to go to. The only thing I have to say is something similar to what Rob said. The problem PHP-FIG has is the fanboys. I'm tired to see some individuals, on reddit / IRC / forums, that when someone asks something, and they paste some code, the only response is something like: "First learn the standards, then ask again".

Well, I've seen that with a paste of only a function. Not even a class or a library. That doesn't help at all and is what I understand as "pushing".

Gravatar
Leric

2013-04-18

That guy is wise to not enable comment on that page, or it'll be really hot.
We don't need to take that newbie so serous, PHPDeveloper.org is the one to blame for publishing such a naive article.

Gravatar
Csanad

2013-04-18

Let me translate this guy posts:

I've found the PSR-0 unfamiliar, I don't like stepping out my comfort zone, I don't like standards at all, because these hurting my ego and independence; and I'm greatly pissed off because so many useful, cool package out there are using PSR-0 so I have to too.

Gravatar
Tom Butler

2013-04-18

I was reluctant to answer this because you seemed to make a point of missing the point and I'm not sure it's worth my time clarifying because it will likely just happen again, but I had several emails asking for my thoughts so may as well write a formal response.

Take a step back for a minute. Forget what PSR is/does, however you want to define it and whatever you think it's "supposed" to be, forget Composer, forget autoloading, forget PHP and answer these questions in order:

1) What is the underlying problem that PSR-0 attempts to solve?

2) Does PSR-0 solve this problem?

3) Is PSR-0 the only way this problem can be solved?

4) If not, what are the pros/cons of other approaches compared with PSR-0?

Phil Sturgeon logic is "Don't bother going past question 2, PSR-0 works, deal with it" which isn't a very helpful attitude for anyone. This narrow-mindedness is a terrible attitude for even a junior programmer, let alone someone who's proposing standards for others.

Let me answer the questions on your behalf.

1) From the PHP-FIG FAQ: "to allow plug-and-play code." Essentially, enable people the ability to drop a library in their project and have it accessible and ready to use. A very nice goal and one I applaud.

2) Yes (providing the library is structured in a very specific manner)

3) No. There are potentially hundreds of methods of achieving this

4) If our goal is plug-and-play then PSR-0 simply isn't the best way of achieving this because it limits flexibility.

The fact you chose to miss the point and back it up by saying "But that's not what PSR-0 is for" is a ridiculous stance, it's exactly what PSR-0 is for and precisely why it fails.

I'm afraid and you've missed the point entirely, why advocate having a standard then say "I don't expect other people to use it". Irrespective of the sentiments behind it, the fact is, people are using it because they're blindly copying what the frameworks are doing. At best the frameworks should be setting a good example. Saying "You don't have to use it" is a cop out, if I want to write a library that works with the major frameworks I'm expected, by framework developers and library users to follow the standard.... why even have a standard you don't want people to use? If the goal is really interoperability then strive for that, not some half-assed middle ground with a list of caveats.

"You really shouldn't be trying to PSR-0 your entire application, that would be suicide."

Indeed it would! And that's precisely why, as an adopted standard, it's poorly designed. Yes, we should have a standard that works for everything... to standardise everything! Take a step back a minute. What is PSR-0 actually trying to achieve? Isn't the overall goal to be able to drop a library into a project and have it just work. That's what PSR-0 offers between frameworks/libraries who follow it and that's good! But the self imposed restriction on use-cases is exactly what my argument is against. What composer offers is far closer to what the standard should define, incidentally, I never said anything about composer beyond briefly mentioning that it supported PSR-0. Trying to pretend I'm arguing against composer is a strawman. I'm not sure whether you missed my point accidentally or just wanted to be able to pretend you rebutted something I'd said; either way it doesn't paint your own argument in a very good light.

My reasoning for providing a metadata along with a library is that it allows project authors flexibility at the same time the library can be "plug and play". If you're following the standard, great, it'll just work (As it does with with PSR-0!), if not, you can do it manually. Much as many frameworks provide a .htaccess file containing mod_rewrite rules, mod_rewrite (and indeed apache) is optional, it just makes life easier for those who are using it. My point is purely one of flexibility.

But, as I said in the post, I wasn't suggesting my example as a potential standard, just an example of how flexibility could be retained. I put a disclaimer at the bottom of the code stating exactly that. I was simply providing an example of something which offers better flexibility than PSR-0 and meets the same goals (drag and drop libraries between projects). Yes, it can be done with composer but in the interest of simplicity I don't want people to have to understand implementation details of Composer in order to understand some trivial example code.

"which constitutes "configuring the autoloader", which the author complained about earlier".

Oh look, I contradicted myself! Wait, no, you missed the point again. There's a clear difference between configuring the autoloader at the application level and at the library level in terms of which developer needs to know about what. Why should the application developer care about the internals of the library? And why should the library author care about the internals of the application? PSR-0 forces both developers to know about each other and what each other is doing, and as such, encourages a very poor separation of concerns. If the goal of PSR-0 is to allow libraries to be used between different frameworks, my arguments against it are simply that it doesn't do this in a very good way! This is the crux of my argument and if you can't understand that application developers shouldn't need to know anything about what libraries are doing internally and library developers shouldn't need to know anything about what framework/application developers are doing then the discussion is pointless. Then again, most PHP developers don't understand why almost all class variables should be private either so it doesn't surprise me that PSR-0 has slipped into the PHP lexicon with little resistance.

Again, all the arguments in favour of PSR-0 seem to be based on the sentiment "It's not designed to do that". I ask again, Why not? It you're going to the trouble of defining a standard and expecting to use it or encourage others to use it, design it in such a way that it's useful beyond a very narrow scope. Flexibility is a good thing, I don't see how you can possibly argue against that!

Most of your post is a strawman. I never said PSR-0 was an autoloader (but it does define how an autoloader should be implemented, which is close enough to be the same thing in terms of flexibility!) , I never said that Composer shared any of its problems, I simply stated that PSR-0 is a poor implementation of what it sets out to achieve. If the goal is really "to allow plug-and-play code." then PSR-0 achieves it, but in a very substandard way. That's all my argument was, everything else you said was attacking things that were either taken entirely out of context (on purpose so you had something to argue with) or just entirely missing the point of what I was saying.

"The PSR-0 standard does not define how autoloaders work. It defines the rules of PSR-0 compatibility, allowing an autoloader to be PSR-0 compatible as well as do whatever else it would like to do, which you've already pointed out is what Zend and Symfony do."

I disagree. PSR-0 says that a class with a specific name will be found in a specific location. This forces the autoloader implementation to work in a very specific way. Yes the autoloader can do other things as well, but the logic behind it must follow a very specific Classname:filename mapping. This is the autoloader implementation.... the implementation being... how it works. The premise of the standard is: "A class with this name will be found in this location". This defines exactly how the autoloader works. My alternative was simply: "Ask the library where its files are" which puts the power in the hands of the developer, not the autoload implementation.

"Every developer who chooses to use it (and that is a fucking lot so far)"

Is that argumentum ad populum you've slipped in there, as if that has any bearing on anything?

To answer your other points, the reason I am annoyed by PSR-0 even though "It's nothing to do with me" is that it sets out with a very useful goal of enabling plug-and-play libraries. I think this is a brilliant plan and something that does need to be standardised and thought through, it annoys me that not much thought has gone into PSR-0 and it's very quickly becoming a standard. Whether Phil Sturgeon claims it or not, PHP-FIG are essentially pushing their standard by default through some very large projects, as are many other developers who follow it because it's The-Next-Big-Thing™ Frustratingly, PSR-0 could indeed be the best thing to happen to the community in years but it scores 4/10 in usefulness so fails miserably, *that* annoys me. You had the opportunity to do something great and used it to do something mostly useless.

Gravatar
Phil Sturgeon

2013-04-18

Hey Tom, thanks for swinging by. You certainly like the word strawman! I'm sorry I missed your points so much but thats mainly because any valid points you had were hidden between bullshit statements about how the FIG were all up in your internets forcing PSR-0's on your mum.

Let's start again now that you've tried to explain yourself better.

1) What is the underlying problem that PSR-0 attempts to solve?

"Aims to provide a standard file, class and namespace convention to allow plug-and-play code."

2) Does PSR-0 solve this problem?

Yep!

3) Is PSR-0 the only way this problem can be solved?

Of course not. PEAR was a thing for quite some time too, and your solution of bootstrapping an autoload class inside its own file in the package is nothing new.

4) If not, what are the pros/cons of other approaches compared with PSR-0?

The advantage of PSR-0 against your approach means you don't need each package to have a JSON files read on the fly, or PHP scripts executed to find your code. Running "bootstrap files" for each package mean extra I/O and extra CPU, instead of being able to use classmap approaches much like Composer does.

"If our goal is plug-and-play then PSR-0 simply isn't the best way of achieving this because it limits flexibility."

If by limiting flexibility, you mean "I need to put each class in a single file, give it a logical name and match the folders to the namespace structure" then sure, this is not very flexible, but I'm fine with that.

If by limiting flexibility, you mean that PSR-0 cannot magically autoload everything in any format at all, then thats entirely right. PSR-0 is a set of rules that allows for autoloaders to simplify themselves, it means that a PSR-0 compatible autoloader can easily know what to do.

What you are proposing is allowing package developers to write code however they want, and have this magic autoloader automatically load everything. There are autoloaders that can autoload in loads of different ways, and you're welcome to use them, or build your own, but it doesn't make PSR-0 wrong for defining a common set of rules to make a PSR-0 autoloader easier to build, and more logical to use.

"Saying "You don't have to use it" is a cop out, if I want to write a library that works with the major frameworks I'm expected, by framework developers and library users to follow the standard.... why even have a standard you don't want people to use?"

It's not a cop out, its the logical answer. If you want to build code for a framework that uses a PSR-0 autoloader (and you want your code to be autoloadable) then you're going to need to write it for PSR-0 compatability. You could write that package however the hell you like, include your own Autoloader.php which handles that logic or force users to run include()s but thats going to be a shit waste of everyones time.

You can build your packages to use PSR-0, and that will be better.

When we say "You don't have to use it" we mean just that! You can do whatever the fuck you like, but if you want autoloadable code in a PSR-0 autoloader then it will need to use PSR-0. Simple.

"[RE You really shouldn't be trying to PSR-0 your entire application] But the self imposed restriction on use-cases is exactly what my argument is against. "

You definitely missed my point here. Your entire application should never be PSR-0, only the code you expect to autoload. I use Laravel 4 and there is loads of bootstrap code, config files, routes, etc. Those files are not (and COULD NEVER BE) PSR-anything.

The use-cases are simple:

1.) Shared packages can be PSR-0, with a nice little src/ or lib/ folder. That's where to autoloadable code lives.

2.) Autoloadable areas go into packages. PyroCMS has a system/cms/modules/users/src folder in each module, which is autoloadable thanks to PSR-0.

Nothing else. We don't need a standard that tells us how to structure our entire application, because that WOULD be restrictive. Nobody ever suggested this, so I hope thats not what you assumed.

"My reasoning for providing a metadata along with a library is that it allows project authors flexibility at the same time the library can be "plug and play". If you're following the standard, great, it'll just work (As it does with with PSR-0!), if not, you can do it manually. Much as many frameworks provide a .htaccess file containing mod_rewrite rules, mod_rewrite (and indeed apache) is optional, it just makes life easier for those who are using it. My point is purely one of flexibility. "

You're using a json file to tell some autoloader which class contains your bootstrap logic. Like I said, you could just include an "autoload.php" via Composer (defined with your composer.json, or tell uses to include it themselves) and this exact same logic would be taken care of.

The main problem I have had with this article, is all you are doing (amongst lots of misguided attacks on the FIG) is suggesting "having a bootstrap file to handle my autoloading logic is better than PSR-0".

Ok, cool, if you think that using a bootstrap file to control your logic is better then SWEET, do that. You can already do that with tools that are available. You can distribute your code this way. You could do this before PSR-0 ever existed, and you can still do it now.

You'll call that a cop-out, but I can't possibly think up another solution.

1.) We delete the PSR-0 standard, tell Composer to stop supporting it and appologize
2.) The FIG projects (myself included) and hundreds (thousands) of package developers continue to happily use PSR-0 and work on the slightly tweaked PSR-X with no change to how things have been going, and you autoload your code with a custom bootstrap file.

Do you have a third?

I'd say you go along with your solution, you can recommend it to your friends, family and blog readers. It'll be sweet. It'll be like a movement or something.

But with all the noise it still doesn't detract from the fact that PSR-0 has helped package developers build their reusable compontents in a specific way to increase their widespred adoption throughout the PHP community.

That's no argumentum ad populum but a mear fact. I'm not saying PSR-0 is good because its popular, I'm saying its popular because it is good. It's aims are simplistic and it achieves its goals. You know it achieves its goals because it has been doing so for years.

Not everyone likes it? Kel surprise, but I'm certainly not going to give you a medal for thinking up "custom autoloaders in a bootstrap might be fun".

Gravatar
Pete Mitchell

2013-04-18

PSR-0 is very simple - it means that when I checkout a 3rd party package I can explore/extend/debug by following the namespace of the classes into a folder structure (it is even better with Sublime Text/CtrlP in vim). As soon as you start putting multiple classes in a file I cannot do that.

It increases the usability of packages (as do namespaces) for developers consuming them by a huge factor.

Invent your own crazy standards on your personal projects that suit your personal preferences, but if you are releasing stuff to the public that you want devs to use then have some professionalism, follow a standard and stop complaining.

Gravatar
Alex Sears

2013-04-18

I agree with Pete. PSR-0 is just one standard. If you don't like it, then come up with a better solution. Maybe someone will agree with you, and then Phil can argue why yours sucks instead of vice versa.

I am a little to young to remember this, but in the '90's the browser wars were in full swing. This caused Internet Explorer to turn into the shitty browser that we all love to make fun of (IE6). They are still recovering, trying to join the party of standards-compliant browsers. Instead browsers like Firefox and Chrome, who support standards and force them on their users through auto-updates, have become the top dogs in the browser market. Apparently there is something to be said for having some sort of standard for people to follow to enable easy interoperability between, in this case, frameworks.

Doesn't anyone remember DRY (Don't Repeat Yourself). If a developer wants to write an extension for multiple frameworks, there should be some sort of consistency so that at least a developer knows his code will autoload correctly! Now he or she just needs to make sure the code itself is correct.

Let's learn from the mistakes of Microsoft and implement some standards to create a better Internet experience, not only for the clients who view the sites but also for the developers who the technology forward.

Gravatar
Ben Harold

2013-04-18

If I wanted to have 100% freedom to write code "creatively" just for the sake of creativity, then I would write everything in brainfuck. I'd rather just make fun of Tom's hair. Tom: you look funny to me.

Gravatar
Tom Butler

2013-04-18

"The advantage of PSR-0 against your approach means you don't need each package to have a JSON files read on the fly, or PHP scripts executed to find your code. Running "bootstrap files" for each package mean extra I/O and extra CPU, instead of being able to use classmap approaches much like Composer does."

Again, the implementation of the autoloader is irrelevant "on the fly" is an assumption. I'd actually have the autoloader cache the paths to classnames and only invoke the autoloaders if it can't find something in the cache or the cache points to a file that no longer exists, but that's an implementation detail that's well beyond the scope of the discussion. Let's be clear: We're discussing a potential standard, not the implementation of the autoloader.


"If by limiting flexibility, you mean "I need to put each class in a single file, give it a logical name and match the folders to the namespace structure" then sure, this is not very flexible, but I'm fine with that.

If by limiting flexibility, you mean that PSR-0 cannot magically autoload everything in any format at all, then thats entirely right. PSR-0 is a set of rules that allows for autoloaders to simplify themselves, it means that a PSR-0 compatible autoloader can easily know what to do."


Exactly on both of these fronts. What you call "magic" is hardly a technical challenge. It's easily overcome by existing tools. The PSR-0 standard is redundant in this regard.


"What you are proposing is allowing package developers to write code however they want, and have this magic autoloader automatically load everything. There are autoloaders that can autoload in loads of different ways, and you're welcome to use them, or build your own, but it doesn't make PSR-0 wrong for defining a common set of rules to make a PSR-0 autoloader easier to build, and more logical to use."

No, it doesn't make PSR-0 wrong but it doesn't make it the best solution either. This is exactly where I disagree. Using a rule-based autoloader like the example I provided, I can supply rules, changing the behaviour of the autoloader without changing the implementation of the autoloader. I have a rule for libraries and I have rules for different aspects of my application which are structured differently. The point is, these aren't hardcoded into the autoloader. I can turn on/off specific rules without modifying the code for the autoloader, simply changing its configuration. This is the essence of several OOP principals and they apply here.

What this means at a practical level is that I can supply an extension to the autoloader along with a piece of code and change its behaviour entirely. The author of the autoloader doesn't need to know anything about what the extension is doing. With PSR-0 the author of the autoloader must include any possible rule in the autoloader. I don't know about you, but I don't know any programmers who are clairvoyant. There are going to be edge cases (See posts on the FIG mailing list) where the library author is restricted by the autoloader, and the stricter the autoloader, the more often this will happen. My suggestion isn't scrap PSR-0, but offer a supplementary method (Such as composer's classmap) of overriding the default behaviour as part of the standard.

Why do you think Apache allows individual directories to supply configuration in a .htaccess file instead of applying the same configuration to everything? Separation of concerns. Not all virtualhosts will use the same configuration, so to offer flexibility the configuration can be altered without apache having to know anything about why the configuration is different, only that it is. This is mirrored with libraries, not all libraries have the same configuration. Yes, a lot of them do, but give people the choice to do something different and make the implementation of how that configuration is overriden standardised.

Going back to the Apache example, the standard is: "The configuration file is called .htaccess", that and the format of the file *needs* to be defined as part of the standard. Writing a bespoke autoloader which does this is self-defeating, other autoloaders will obviously not do the same because it's not part of the standard.

"You could write that package however the hell you like, include your own Autoloader.php which handles that logic or force users to run include()s but thats going to be a shit waste of everyones time. "

Exactly! I want people to be able to write the package however the hell they like and include a autoloader.php. But, for plug-and-play the standard should define what that autoload.php is and how it's structured. This kind of autoload.php which gets automatically called once per library is, at the most basic level *exactly* what I'm proposing.

If the standard said "autoload.php at the root of the library gets automatically included" I'd be happy.

As you say, Composer can be used for this, but it's a bit too wide in its scope to be suggested as a standard. However, perhaps the standard should be to offer an autoloader which supports a few composer features. This would be annoying for developers of the autoloader to support though which is why a simpler, easy to implement standard such as "autoload.php in the root directory gets called" is what I'm advocating. It can happily work alongside PSR-0 *and* offers flexibility. I'm still struggling to see why there's so much resistace to this?

My sample code isn't a PSR-0 competitor, you're right, it's something we need that can optionally work alongside PSR-0 (As I showed, people can easily use both!) that offers people flexibility while still being standardised. The standard needs to provide a standard way for people to configure the autoloader, or just include all their files.

"When we say "You don't have to use it" we mean just that! You can do whatever the fuck you like, but if you want autoloadable code in a PSR-0 autoloader then it will need to use PSR-0. Simple."

*facepalm* And again, you're missing the point! I don't have to use PSR-0 but it is fairly standard these days and the way it works is limiting. I know I don't have to use it, but I'm trying to point out the flaws in it because it's a good idea that could be done better rather than turn a blind eye and let the community as a whole suffer because of some poor design decisions people made 4 years ago.


"You definitely missed my point here. Your entire application should never be PSR-0, only the code you expect to autoload. I use Laravel 4 and there is loads of bootstrap code, config files, routes, etc. Those files are not (and COULD NEVER BE) PSR-anything."

Again, you're focussing too much on "What does PSR-0 currently do?" rather than "What is problem that PSR-0 attempts to solve?". Config files, routes, MVC components, metadata on how these can be autoloaded can be registered with the autoloader in the exact same way, using my example, by providing rules for them. All of these things are libraries in an abstract sense. Why treat them differently? Yes they have different autoloading rules, but there's no reason they couldn't be registered with the autoloaded in a standardised way. If the autoloader was flexible and just had rules added to the stack this is easily possible!


"Nothing else. We don't need a standard that tells us how to structure our entire application, because that WOULD be restrictive. Nobody ever suggested this, so I hope thats not what you assumed."

Not at all, and that's part of my point. It is a self imposed restriction. Why shouldn't other parts of the application be registered with the autoloader in the same manner? That was my point. Somewhere you need some logic which says "For these classes, load the files in this way". Rather than hardcoding that into the autoloader it makes more sense for any arbitrary component in the system to be able to tell the autoloader: "This class is here!". How that's done is an implementation detail, but that's what the basis of the standard should be. Not the other way around like PSR-0 which as you just said, has a limited set of use-cases. Remove that restriction!

I know you'll say "PSR-0 isn't designed to do that". And again, I understand that, but that's because PSR-0 isn't designed the right way to begin with. No PSR cannot be used for this, and that's precisely why it's a poor standard.

"You're using a json file to tell some autoloader which class contains your bootstrap logic. Like I said, you could just include an "autoload.php" via Composer (defined with your composer.json, or tell uses to include it themselves) and this exact same logic would be taken care of."

As I said, I'd be very happy with this kind of implementation! I think composer is a little heavy-handed if you're using it solely for such a trivial task but this is something I would indeed be happy with. But, it needs to be standardised. Ideally at a level that allows people to follow the standard without being forced to use Composer (Damn Separation of Concerns, again!)

"2.) The FIG projects (myself included) and hundreds (thousands) of package developers continue to happily use PSR-0 and work on the slightly tweaked PSR-X with no change to how things have been going, and you autoload your code with a custom bootstrap file."

I have no problem with people using PSR-0 beyond the fact that it shouldn't have become so widespread in the first place. It took off because it was a solution to a real-world problem with no competitors. It's not "popular because it's good", it's like saying the only entrant in a race is "good" because he won it. It's popular because there's aren't any alternatives. Yes, we're stuck with it. The second option is fine, but it needs to be flexible. The fact is, PSR-0 isn't flexible enough and I was simply highlighting those flaws. If people don't highlight the problems then everyone carries on oblivious.

What you do with that information is up to you, but I've made my case for why a standard should be implemented differently and if you honestly can't see why standardising a method for extending the behaviour of the autoloader rather than standardising everyone's directory structures is useful to the community then I really don't think it's worth continuing this discussion.


"is all you are doing (amongst lots of misguided attacks on the FIG) is suggesting "having a bootstrap file to handle my autoloading logic is better than PSR-0"

Yes! Exactly! But with a slight amendment, having a bootstrap file with a standardised name and structure that the autoloader can locate. That's it. That is all I was suggesting, and it is indeed better than PSR-0. The standard should simply define the name and structure of that bootstrap file. I don't care about the implementation details and provided a very simplistic piece of code purely for demonstration purposes (as I said!). Whether it uses autoload.json, autoload.php, bootstrap.php or loadmegoddammit.php I don't care as long as the result is that some user-supplied PHP code gets called from the autoloader as a result of it.

Gravatar
Phil Sturgeon

2013-04-19

"Yes! Exactly! But with a slight amendment, having a bootstrap file with a standardised name and structure that the autoloader can locate. That's it. That is all I was suggesting, and it is indeed better than PSR-0."

If that is all you were saying, that is all you should have said. Your attitude was way off, you made a bunch of assertions that were incorrect and generally acted like an asshole.

Having an "autoload.php" sounds lovely. I personally do not NEED to include that custom autoload logic, because I know that my code is going to be loaded by a PSR-0 autoloader.

Tadaaaaaaa.

When the Package Autoloader (PSR-X) comes out I will have a few more options, yay for that, but it's still going to be based on rules.

If you would like to autoload your code in this way, then go for it. The FIG don't need to, because we all agreed to use PSR-0.

And that's why the call us the Framework Interoperability Group.

Gravatar
Tom Butler

2013-04-19

And you hit the nail on the head: unless that autoload.php is standardised, it doesn't work. My argument all along has been that PSR-0 is restrictive and it's become the standard. These two things do not mix well. Whether or not *you* personally need that custom autoload logic, there are projects which would benefit from it and if you're suggesting a standardised autoloader and want people to use it (or indeed practically force people to use it if they're using a framework that uses it), having a restrictive standard is needlessly divisive.

If PSR-0 did only affect framework authors (for which it would have to only load framework internals) and not library authors then claiming "It's only for frameworks" is perfectly valid. The fact is, it doesn't only affect framework authors, in 2013 it pretty much affects anyone who releases any code. Not good.

My argument was that the standard is restrictive based on the needs of a very small group 4 years ago but has spread to the point where if I release a package I get complaints that it's not been used. This wouldn't be a problem if the standard was flexible to begin with. Yes, PSR-0 meets some basic requirements but it doesn't meet it's own goal of allowing "plug-and-play" libraries because it makes itself needlessly awkward to support, and is a nightmare for older libraries! I can't provide an autoload.php in my library because it's not implemented by all the autoloaders like PSR-0. However, If the standard defined an extensible autoloader as I suggested you wouldn't need PSR-0 *or* PSR-X. Each library would simply define its own autoloader and avoid the problem entirely and simply not care what the framework was doing.

This is my issue with PSR-0 and why it is short-sighted. It's a separation of concerns issue, a library author shouldn't be restricted by design decisions the framework author made.

Gravatar
Phil Sturgeon

2013-04-19

Done!

https://gist.github.com/philsturgeon/5417208

Gravatar
Watts

2013-04-19

I know this is my particular hobby horse, but one of the things I've found most appealing outside the PHP world is how plug and play libraries often are -- Ruby gems, Node packages, Python "eggs," Perl line noise (that may not be their official package name). As it turns out, all of these systems have pretty rigidly defined conventions: file and class naming conventions, source layout, configuration files, and so on. Putting together a package for Python or Ruby or Node is a little bit of a pain in the ass, because you have to follow those conventions.

But this is also what makes them so damn great. And bluntly, it's what makes so many people flock to those ecosystems instead of PHP. Have you *used* Rails lately? Half of what you do is effectively snapping together Legos. Python is quieter about this, but in some ways their packages are even more interoperable because they don't have one framework dominating their language the way Rails does Ruby -- I could be using web.py, Flask or Pyramid with essentially the same packages.

In Python and Ruby, some of this is actually baked into the language. It isn't in PHP. Frankly, I'd be perfectly happy if some future version of PHP *did* bake in PSR-0, but if the community moves toward it on their own, fantastic. PSR-0 may not be the One True Perfect Autoloading Standard, but everything I've seen in the web development world across all the other communities -- and *now* across PHP, thanks to PSR-0, Composer and Packagist -- leads me to *very* deeply believe that universal acceptance is more important than perfection.

Gravatar
Tom Butler

2013-04-19

Hah, Of course it's easy to implement an autoloader which does this or something similar but it's not the autoloader that needs to be defined, it's the standard for everyone to follow, which was my point all along. It's easy to implement a PSR-0 autoloader but if nobody knows about the standard or follows it, it's pointless. That still seems to be the point you're missing, to make autoload.php (or any similar solution) it needs to be part of the standard, and why PSR-0 isn't the best answer to the problem it tries to solve-plug and play libraries.

(Your joke suggestion doesn't really work either because it doesn't load autoload.php from the library's directory)

For what it's worth, I'd also suggest having the included file return the path (relative to the library dir/location of autoload.php) to the autoloader rather than simply including the file. This puts the responsibility of loading the file back in the autoloader and the responsibility of finding it in the library. The advantage of this is that the autoloader can do what it likes with this information, for example, caching it. But again, this is why any standard needs discussion surrounding implementation details rather than posting a piece of code at 1am based on a couple of blog comments.

Gravatar
Tobias Hoffmann

2013-04-19

I think you both are right, and you both are talking past another; and the point is made clearly by both of you.


This is how I interpret your positions:

The FIG more or less distilled the common ground for library organization from projects such as PEAR and Zend Framework and others, most of which used similar-but-not-quite-the-same conventions for organizing and loading classes. This culminated in PSR-0, which made most voters happy without requiring large adjustments to their libraries, since they were already almost conformant. New libraries often then used this same PSR-0. This "standardization" obviously made life easier for many people. Since PSR-0 librarys are pretty sharply defined in structure, there is either great overlap with other conventions, allowing authors to easily adopt to full PSR-0 compatibility, or rather few overlap; in which case people would just add another autoloader to the chain (one of which might be the upcoming package autoloader PSR-X). No harm done!

What Tom seems to be suggesting is that the scope of PSR-0 isn't broad enough, since it does not work with many other library structures. As said, that was never the scope. PSR-0 is about wrapping up the predominant library/autoloader style to make transitioning to a common library/autoloader style painless, and to clear doubts for authors of new libraries wether to conform to PEAR or Zend Framework or whichever mostly identical library/autoloader standard - just use PSR-0, and you're safe. As stated over and over, your proposed autoloader could be another PSR (go for it), or it could be added in an autoloader chain - it will just not replace PSR-0, because PSR-0 is a team effort where every voting party compromised to reduce library/autoloader complexity - not to produce *the* all-encompassing autoloader solution.


So, that's how I see your positions, and I'm with Phil here because you seem to think PSR-0 is excluding you from something, and that's not the case.


However, the introduction of PSR-0 is IMO a little problematical: "The following describes the mandatory requirements that must be adhered to for autoloader interoperability." This statement is true only if viewed in the very narrowly defined mindset of PSR-0, but not in the larger world, where alternative autoloaders can rightly make that same claim - and I can understand some of the attitude blowing against PSR-0 for purely that sentence. This is purely a problem of rhetorics, however. Maybe reformulating it into something like "The following describes the mandatory requirements that must be adhered to for PSR-0- autoloader interoperability." would be sufficient. Just as PSR-X or PSR-Z could have the statement "The following describes the mandatory requirements that must be adhered to for PSR-?-autoloader interoperability."


Phil, Tom, did I get you right here?

Gravatar

2013-04-19

Tobias: Right, Tom has a valid point (using custom autoloaders with a bootstrap file is nice) but his thoughts that this is A) new B) important C) grounds for a standard D) something that NEEDS a standard or E) proof that the FIG have been wrong all along, are all making me laugh so hard I'm struggling to keep this conversation constructive.

Tom: I feel like your approach is purely theoretical. Who is it having these problems? If you are distributing your code with composer.json then you do not need your proposed "standard" (more of a convention), because you can hardcode the autoload.php to be included and automatically fire it off. If you are NOT using composer to distribute your code, then where is this extra code for the autoloader going to live?

If you are using something like PHPAB https://github.com/theseer/Autoloadto autoload your code, then your standard is still going to suck, because that autoloader won't know what is going on either. Sure, we could change all these autoloaders to just know that autoload.php needs to be included, or we could make it so that the json file is included to help load the right autoload.php, but what is the point of all this?

If you are building a distributable shareable package, its going to be using Composer and therefore you don't need this at all. If you are building an application then you can register your custom autoloader and fire off spl autoloader, and the job is done.

Moving this SPL autoloading into a class which registers itself with another class just so you can implement some interfaces and whatnot, you're actually reducing the portability of this code, and making it considerably less useful.

I'd be really interested to hear some real-world examples of A) what is this code which PSR-0 is too rigid to autoload and B) examples where your autoload.php solution would be better than simply registering with Composers autoloader.

Without those examples we have nothing further to discuss. It could be that you're a genius and your hiding it well, or it could be that you're wasting everyones times with a theoretical problem that doesn't actually exist. I'd like to know which it is before we continue.

Gravatar
Phil Sturgeon

2013-04-19

Further thoughts Tom: I took the stance of "against" quite clearly, because your original article was full of bullshit which dwarfed out your points. Since explaining them here you've explained your intentions slight better. While I am sure your approach has a place in the world, I feel that the place is very small, especially when the existing tools can do this job perfectly.

Beyond that It feels like you see the PHP world as one ruled by a restrictive regime, whereas for the last 10 years I've seen it as a crazy fucking shit-show with no standards and messy crap from PHPClasses.org being the solution to as many problems as it caused. The entire PHP ecosystem has grown up THANKS to PSR-0 and you seem to think this was a mistake, which is obviously rather confusing for somebody who has been coding PHP for a decade.

If you would like to propose a standard, get Composer, PHPab (and whatever other autoloaders) along with the FIG to go along with it (if you want any chance of getting the community to care) then polish up a proposal with exact implementation details, and send a pull request to the FIG.

Remember, be nice. Being an asshole about the FIG is not going to win you any favours, and your only alternative would be to make a FIG competitor, which is just going to be a massive waste of everyones time.

If you have a valid approach then people will support you. If you don't have a valid approach then people will ignore you.

I, personally, will be ignoring you. But I do wish you the best of luck.

Gravatar
Brian

2013-04-20

Could someone explain to me why the PHPab autoloader solution is not a better solution than the PSR-0 autoloader? I cannot see it!

The PSR-0 autoloader forces me to use different autoloaders for different classes if I use a library of classes that doesn't support the PSR-0 (legacy code fx.) namespace definition and directory structure, which is exactly what we encountered trying to get PSR-0 working on a huge project.

The PSR-0 also forces me to use a very specific directory structure which may or may not fit into the way we want to organize our files. We cannot reorganize a huge library of legacy classes, but we still need to use those as many clients applications are based upon these.

I would never use more than one autoloader in a project so I need the solution to fix these problems otherwise using the PSR-0 makes no sense.

I cannot, no matter how much I try to understand it, see why such a restricting solution has been developed. It seems like because it fits very well into the agenda and structure of the most popular frameworks, then what ever problems it might cause for other projects, we just don't care about it.

Gravatar
Peter

2013-04-20

Tom: .htaccess is not an example of separation of concerns, somewhat misusing the term. Its interesting that you bring apache into arguments - a web server many devs are moving away from due to it's complexity of configuration.

So far you have required a lot of prose to explain your ideas, there is a not an insignificant amount of complexity in the ideas you are putting forward.

PSR-0 is successful because it is explained in 7 bullet points and an example autoloader is provided in ~10-15 LOC.

Any improvement on the PSR will have to be equally as simple, otherwise it will not be useful. Simplicity should always valued over any thing else - especially important when working with other devs.


This talk from Full Frontal last year explains the importance of simplicity quite well.
http://www.youtube.com/watch?v=KTqIGKmCqd0

Gravatar

2013-04-21

Brian: PHPab is not a standard. It is a shitload of code which allows you to autoload anything. PSR-0 is a simplified autoloader, which is obviously not going to magically autoload old code.

"The PSR-0 autoloader forces me to use different autoloaders for different classes if I use a library of classes that doesn't support the PSR-0 (legacy code fx.)"

Correct. Going forward your new code can be PSR-0, instead of a random-hodge-podge of whatever. If you also need to autoload your old code, you'll need to use an autoloader that can load it. Enter Composer or PHPab.

"The PSR-0 also forces me to use a very specific directory structure which may or may not fit into the way we want to organize our files."

Correct. By requiring a specific structure, the complexity of the autoloader is drastically reduced, meaning when you dont have a shitload of legacy code in your application you will no longer have to worry about having complicated autoloaders, just a PSR-0 one.

"We cannot reorganize a huge library of legacy classes, but we still need to use those as many clients applications are based upon these."

Don't, that sounds terrible.

"I would never use more than one autoloader in a project so I need the solution to fix these problems otherwise using the PSR-0 makes no sense."

PHPab and Composer both help generate a single classmap, using multiple autoloading logic. So really, you're using multiple autoladers.

"I cannot, no matter how much I try to understand it, see why such a restricting solution has been developed. It seems like because it fits very well into the agenda and structure of the most popular frameworks, then what ever problems it might cause for other projects, we just don't care about it."

Are you kidding me? Converting PyroCMS is a mission and a half. It's not easy, but its making the code a lot cleaner, meaning we can integrate all sorts of amazing packages and share our code with the entire PHP community instead of just some CodeIgniter or PyroCMS fans.

If its hard work for you, and you don't see the benefits, then don't do it.

The way I see it is, the PHP-FIG has decided the members are all going to speak Spanish. Package developers can also opt in to learning Spanish going forwards if they want to (and many have), and a lot of the community has also decided to start learning Spanish so they can interact with us. That doesn't mean the entire PHP community has to immediately learn Spanish, you can keep speaking whatever you like and require as many translators as you need if that works for you. Or, you could just learn Spanish. It's hard work, but would eventually put you on a totally level playing field with the vast majority of the community.

Gravatar
Brian

2013-04-22

Dear Phil

Thanks for your reply.

"Correct. Going forward your new code can be PSR-0, instead of a random-hodge-podge of whatever. If you also need to autoload your old code, you'll need to use an autoloader that can load it. Enter Composer or PHPab."

Which is one of the points that doesn't really make sense to me when I can just use PHPab for both old and new code, whereas if I use PSR-0 I need that and then some.

"Correct. By requiring a specific structure, the complexity of the autoloader is drastically reduced, meaning when you dont have a shitload of legacy code in your application you will no longer have to worry about having complicated autoloaders, just a PSR-0 one."

IMHO the complexity of the autoloader shouldn't be solved by forcing something like a specific directory structure upon each project. This makes no sense and really it reveals that there is something very wrong with this solution. Rather the solution, which agreed must still produce a simple autoloader, needs to be able to load every kind of code without imposing restrictions that doesn't make sense to many projects. PHPab is such a solution.

PHPab is one single autoloader and there is no complication what so ever.

"PHPab and Composer both help generate a single classmap, using multiple autoloading logic. So really, you're using multiple autoladers."

No. PHPab generates a single classmap, but it doesn't use multiple autoloading logic. It uses one very simple autoloader for everything and since it generates a classmap it can load both PSR-0 directory structures and whatever directory structure needed. PHPabs autoloader is more simple than the PSR-0.

"Are you kidding me? Converting PyroCMS is a mission and a half. It's not easy, but its making the code a lot cleaner, meaning we can integrate all sorts of amazing packages and share our code with the entire PHP community instead of just some CodeIgniter or PyroCMS fans."

I see several problems with this:

1. You're stating that converting PyroCMS is a big task, one that is not easy. In reality no such conversion should be necessary.
2. The conversion is making the code cleaner? How? Code cleanliness has nothing to do with directory structure.
3. You can now integrate all sorts of amazing packages and share code. Sure, but you could do that all along with a solution like PHPab without having to change anything, using whatever library, class, project, framework, you like, PHPab would load it all from wherever you want it to be with just ONE single and simple autoloader.

"PHP-FIG has decided the members are all going to speak Spanish."

Yes, and that's one hell of a solution to such a simple problem which PHPab solves without us having to do anything except for the generation of a ONE single classmap that will be loaded by ONE single autoloader - no other restrictions.

We're using Git for our projects, like most PHP projects are, we have one pre-commit hook which generates the classmap automatically with PHPab. We can use whatever package, project, library, etc., we want, with whatever directory structure that package is using, we don't even care, PHPab solves all of those problems without us having to change anything.

When the PHP-FIG is confronted with the above all I hear is: Then don't do it! Then don't use it!

That's no answer. I hope more people will try PHPab out and compare it to the unnecessary restrictions that PSR-0 is producing.

Gravatar
Tom Butler

2013-04-22

> Tom has a valid point (using custom autoloaders with a bootstrap file is nice) but his thoughts that this is A) new B) important C) grounds for a standard D) something that NEEDS a standard or E) proof that the FIG have been wrong all along

A) If it was new, FIG would at least have have an excuse for not thinking through what they were doing 4 years ago. If it was possible to say PSR-0 was the best answer available at the time, then it would at least be excusable that it's been designed in this way.

B,C,D) Of course it's important! If it's not, then PSR-0 isn't important either! Again, PSR-0 solves the problem of plug-and-play. However, PSR-0 isn't the only solution to this and may not be the best.


> If you are distributing your code with composer.json then you do not need your proposed "standard" (more of a convention), because you can hardcode the autoload.php to be included and automatically fire it off.

Composer is fine, but, by that logic PSR-0 is equally redundant. You could include an autoload.php and register your own autoloader which used PSR-0!


> If you are NOT using composer to distribute your code, then where is this extra code for the autoloader going to live?

That depends on the framework. All the framework has to do is know when to load the autoload.php and what to do with it. The implementation of this is, of course, down to the framework author, and surely that's a good thing for everyone?

> If you are building a distributable shareable package, its going to be using Composer and therefore you don't need this at all.

Or indeed PSR-0. So why does PSR-0 exist either? It's a moot point. PSR-0 exists to solve a problem, that problem can be solved in many ways.

> Moving this SPL autoloading into a class which registers itself with another class just so you can implement some interfaces and whatnot, you're actually reducing the portability of this code, and making it considerably less useful.

...what? The autoload.php would be ignored entirely by applications which didn't follow the standard. How does that reduce portability? It's like saying including composer.json reduces portability. Where does the code that reads composer.json sit? What a silly thing to say!


> I'd be really interested to hear some real-world examples of A) what is this code which PSR-0 is too rigid to autoload and B) examples where your autoload.php solution would be better than simply registering with Composers autoloader.

A) You only have to look at the PHP-FIG mailing list to see people posting about problems they have! Why do you think people are moving to PHPab after looking at PSR-0 and deciding it's not up to the job? There's a very good example here regarding a non-trivial problem caused by PSR-0: http://scriptogr.am/mattsah/post/a-useful-critique-of-psr-x which I'm sure you've seen, the point is, library authors want a choice about how their libraries are structured PSR-0 removes that choice. How is limiting choice a good thing?

Here's another trivial example:

I have a helper class which essentially acts like a C++ struct. In many cases they only have meaning within the scope of a single specific class in order to provide it some configuration/data. You'd never load the struct unless the core class was also loaded as it's meaningless to anything else in the application and the core library class needs the struct loaded to be configured. It often makes sense to group these in the same file because changes in the struct definition requires changes in the logic which uses it, in terms of code structure, version control and for portability. SRP would suggest that these are a single responsibility, as such I'd argue they belong in the same file. Using PSR-0, as an application developer I must ensure that the core is loaded prior to the struct. However, what if an instance of the struct was passed into the core's constructor? Now you have a problem with PSR-0; it's impossible to initiate an instance of the struct unless the core class is initialised first, of course that can't happen because the core can't be constructed without the helper/struct and the helper/struct can't be initialised because it can't be autoloaded.

Sometimes it just makes more sense to store multiple traits/classes/interfaces in the same file. PSR-0 makes this impossible.

B) For the exact same reason that PSR-0 is better than simply defining the class map in composer.

My argument is simple: PSR-0 solves a problem, there are many ways to solve that problem, PSR-0 isn't the best so why are we using a substandard approach? Moreover, why didn't PHP-FIG recognise this to begin with (or, even now?)

> The entire PHP ecosystem has grown up THANKS to PSR-0 and you seem to think this was a mistake, which is obviously rather confusing for somebody who has been coding PHP for a decade.


I never said it was a mistake. What PSR-0 set out to do was indeed a good thing as I have said all along, it's just a poor solution to the problem at hand. I'd argue it's been composer more than PSR-0 that's improved the PHP ecosystem in the last few years. PSR-0 has little to do with it, Composer could use any standard and people would follow it.


@Peter:

> PSR-0 is successful because it is explained in 7 bullet points


1) Place autoload.php in the root directory
2) It will get run automatically


There, I explained an alternative in two. And before you say "But that doesn't tell people how to implement their autoloader", that's exactly my point; the implementation is down to the application author. The library author knows the above two points and *nothing* else about the application their library is sitting within. PSR-0 forces library authors to know what framework authors are doing and forces application authors to know what library authors are doing.

Gravatar

2013-04-22

Brian: "When the PHP-FIG is confronted with the above all I hear is: Then don't do it! Then don't use it!"

That is exactly right. Your primary concern is autoloading new and old code with a single autoloader, the FIG generally does not have that much legacy code. Symfony, Drupal, Zend, Symfony, etc are all building their new apps using PSR-0, so they only need one autoloader. This is something all of the projects are perfectly happy to do.

Laravel 4 is also using PSR-0 for example, so anyone building a new application with L4 is going to be making a PSR-0 application.

This is all fine with us, we are not trying to magically autoload old AND new code, because we only have new code.

If you need to autoload your old code, you should use an autoloader that can autoload your old code. it couldn't be any simpler than this, right?

PSR-0 only because a problem for you, if you try to force its existence on a legacy project with a shitload of old code.

It's become a problem for me on PyroCMS because we have a load of old CodeIgniter code and we're switching to use Laravel 4. Really I'd just rewrite this, but then our users would be screwed. Moving it from using CI specific code to using generic PSR-0 code means we are cleaning up our codebase, by deleting as much old legacy code as possible and replacing it with new, PSR-2, unit-tested awesome framework agnostic code. but im not going to try and make the PSR-0 autoloader magically autoload my CodeIgniter code, nor do I need to. CodeIgniter will load the CodeIgniter code, PSR-0 will load the PSR code, and over time more and more of the codebase is going to be PSR-0.

That detracts from my point. When the FIG say "Then don't use it" its not a cop-out. The FIG is not trying to create an autoloader that loads any code ever, that is an implementation level detail which is irrelevant to the goals. If PHPab works for you better than converting all of your PHP code to a new standard, then don't use that standard. You absolutely don't have to, and anybody who says you do is being a fanboy troll.

Tom: Nope.

Gravatar
Ben Harold

2013-04-22

tl;dr;

The question: I have a solution to a problem. The solution is (int) 4. What is the problem?

Phil says the problem is 2 + 2. He acknowledges that this is not the only possibly problem that leads to the solution. If you like a different problem better, he's fine with that.
The hive mind says the correct problem is either (sqrt(64) / 2) OR ((4 ^ 0) * 4) OR (6,443,327 - 6,443,323), and if you don't agree, they're going to keep talking forever.

Gravatar
Lossendae

2013-04-24

> I never said it was a mistake. What PSR-0 set out to do was indeed a good thing as I have said all along, it's just a poor solution to the problem at hand. I'd argue it's been composer more than PSR-0 that's improved the PHP ecosystem in the last few years. PSR-0 has little to do with it, Composer could use any standard and people would follow it.

Both of them have been a huge help.
You're minimizing the impact of standards shared across different projects.

I don't know nor do I care about the code you're producing, but imagine that i have to use a feature provided by a 3rd party, equal quality wise, that you and a PSR-0 friendly give to the community, i'll rather use the PSR-0 friendly code.

You're viewing the whole concept with the eye of a developper who can or want to think of whatever he need and code it like he want regardless of what the rest of the world think.

PSR and Composer is also growing fast because it's accessible to less "gifted" developper, who can't nor do want to make their own bootstrap autoloader. But good enough to have good simple ideas that they can code following common rules and release.
And have other people eventually use it, improve it, fork it, be inspired by it, learn form it.
Easily. Without having to learn each autoloading magic in each projects.

PSR's are dead simple, and it happen that those rules are collectively followed (and designed) by many important PHP projects. So yeah, they're popular.
They're not forcing you to use their standards.
They just have take the initiative to have common rules, and tell the world about them.
I highly doubt that the FIG's people agreed for each and everything, but they have made a choice to follow rules that they votes collectively for.

If you don't like them, don't just rant on your comments-off blog, be a genius, apply for the group, and propose your solution and see what happens next.
Or use your solution wherever you want, and don't complain because they speak spanish.

Posting comments after two weeks has been disabled.