PHP-FIG: Autoloaders, Amendments and The "15th Standard"

Posted: 2014-02-13
Category: PHP

I've managed to get myself involved in a lot of projects in and around the PHP community because I like to offer my advice, experience and time to trying to make things better. Recently, I've been putting in lots of time for bits around the PHP-FIG.

Like it or not, tabs or spaces, PSR-2 or no, the PHP-FIG has had a huge impact on the PHP community and it's going to continue to do so. We have more PSR's in the works now that at any point before, and they're awesome ones.

PSR-5: PHPDoc

In Draft status and being worked on hard, most actively on GitHub. My guess? 6 months... probably.

PSR-6: Cache

Two years in the making? Ha. Well, we never used to have a workflow, so I spent a few months creating, editing, convincing and pushing through a workflow bylaw for that. The workflow stops multiple alternative proposals from being supported by different members and having this crazy duel between two totally disparate files. That was nuts!

This workflow should get PSR-6 moving along, and I've suggested to the chap in charge that now would be a great time to bump it up to "Review". getting it one step closer to completion and forcing updates to be small. There's nothing big left on the todo list, so that seems like a decent plan.

PSR-7: HTTP Message

This one is mainly being worked on by Michael Dowling, from AWS and Guzzle fame, but has my name on the bill as a coordinator much like PSR-4 and PSR-5. This one is very fresh and still in Draft stage, but will start picking up steam once the rest of the FIG take a look and offer feedback. I'll be pushing that if it doesn't happen fairly soon.

You can see a full index of PSR's along with their statuses here.

So, progress is happening but I feel like we still have some problems at the FIG, and I would like to solve these issues.

The following is almost entirely just my opinion, so others in the FIG do not necessarily agree. If we all agreed about everything it wouldn't be very representative of the PHP community at large.

Problem 1: PSR-0 AND PSR-4?

Some people have been calling the FIG a laughing stock because we have two active PSR's that achieve the same goal: autoloading.

This "You can use either one" approach was (in my head at least, as coordinator of this PSR) intended to provide a "grace period" for people to upgrade without making them freak out and think they had to rush.

PSR-0 and PSR-4 both do the exact same thing: they autoload code, and they do it in a 100% compatible way unless you're a PHP 5.2 project making use of legacy "poor mans namespaces", which was an old convention where _ would be converted to folder separator. Zend, Symfony, PEAR all did this for their code and a lot of projects like PHPUnit and Twig currently require that, and PHP 5.2. Those projects are big, and sometime they should upgrade, but that is what deprecation means: put it on your todo list.

I've seen some people piss and moan about PSR-4 and it's namespace prefix support. For those of you unfamiliar with the feature, it means this:

vendor/league/fractal/src/League/Fractal/Resource/Collection.php

... can be shortened to this:

vendor/league/fractal/src/Resource/Collection.php

But let me be clear, that is an optional usage of PSR-4, and an optional feature in Composer too. If you would like to continue to be that verbose structure in your own code you're welcome to.

To compare, this is how I achieved the shorter folder structure in the example above:

    "psr-4": {
        "League\\Fractal\\": "src",
        "League\\Fractal\\Tests\\": "tests"
    }

If you would like to continue using the more verbose folder structure known in PSR-0 then great, simply change the above to this:

    "psr-4": {
        "League\\Fractal\\": "src/League/Fractal",
        "League\\Fractal\\Tests\\": "tests/League/Fractal/Tests"
    }

Once again, PSR-0 folder structures are supported, and that example loads this identical path to the PSR-0 example:

vendor/league/fractal/src/League/Fractal/Resource/Collection.php

That means PSR-4 is a completely compatible replacement for PSR-0, with the exception of dropping support for a long unsupported version of PHP, which helps us gladly ditch an edge case bug, and provides a great optional feature to those who felt like it was frustrating as f**k to have to replicate their entire folder structure every time. Literally no downside there.

Paul Jones and myself agreed (I think) that once PSR-4 was approved then the two would be "alternatives" for a while, then we'd eventually deprecate one. Deprecating PSR-0 now (or soon) sends a message, that PSR-4 is the preferred successor, and you should work on getting onto it at some point. You can still use a "deprecated" PSR, and no PSR will ever be "deleted" (maybe it could be "unrecommended"), but we should definitely deprecate it as we do not need both to be considered "recommended".

If you're using PHP 5.2 forever, then you can keep on using PSR-0 forever, but The PHP Group suggests you should upgrade to PHP 5.4 and the FIG suggests you upgrade to PSR-4. That's fine. You can ignore both of us forever.

I'm going to try and get PSR-0 deprecated, but first I have to complete a sub-quest...

Problem 2: Amendments

We have a situation where PSR-1 depended on PSR-0, and if PSR-0 is ever deprecated or not, anyone who switched from PSR-0 to PSR-4 is suddently technically in violation of PSR-1.

  • Namespaces and classes MUST follow [PSR-0].

Well, that should say:

  • Namespaces and classes MUST follow [PSR-0] or [PSR-4].

Right? WRONG. I'm not going to complain about that again because I did it in a video already.

People were super against our potential future selves saying "Look, they edited this file once, so now we can change things willy nilly!".

Erf. So to avoid that I've come up with an amendment bylaw which states that you can't make changes except some reasonable conditions. Here is a real short summary:

Deprecation and Replacement

Shove a link at the top of the old one saying: you should use this newer one instead, if you can.

Dependencies

PLEASE try and avoid them, but if you have to then put them in a "dependency list" which can always have new items pushed onto the stack but never have any removed. This is dependency injection for markdown. BOOM.

Annotations

If something needs to be clarified with errata, we can shove a link into the original document to link to the errata line in the meta document, otherwise people have literally no idea it exists.

Formatting & Typos

Our table syntax on GitHub is broken, or some fucking Englishman snuck a British spelling past the group? Or straight up spelled something wrong? Fix that.

The full Pull Request is here.

I'm probably going to put this to a vote for the rest of the group over the weekend, but as people who potentially use these standards, do you love or hate the idea of new standards coming out, old ones being deprecated and new ones being recommended? I know that it might seem like a lot of fuss as PSR-0 and PSR-4 is the first replacement, it's not the only time its going to happen, because...

Problem 3: PSR-2 needs to be replaced

I'm into that idea, and Pádraic Brady (ZF's FIG rep) is not against the idea if you have a look in the comments.

PSR-2 was never intended to be a 100% complete style guide. It was essentially split off of PSR-1 (considered for a while to be named PSR-1 Basic and PSR-1 Advanced) because some of the rules were considered so contentious that they would effect uptake of PSR-1 itself. So, we have this extra PSR-2 code style guide that huge projects like Laravel flagrantly ignore and which SF2 and ZF2 say they use but technically violate a few things in every file.

What we need is...

14 standards...

So replacing PSR-2 with PSR-Whatever would definitely get us up to 15 standards, but if we have a deprecation and replacement process set up then we're back down to 14... so it's not all that insane.

If we take the extensive guides from Drupal, Symfony, etc into account and can make something that is truly a logical merge of them, then we can potentially cut things down from 14 to maybe about 5. With PSR-1 and PSR-2 helping to bring a LOT of projects closer to the same style we're definitely making improvements to the situation, but we have a long way to go.

How would you feel about a more involved PSR for code style based off of PSR-2 but drastically improved?

It would almost definitely still involve spaces instead of tabs so don't freak out over that one, but it would take care of all the weird edge cases that have come up during the lifespan of PSR-2, like this or this or any of these. That last link is a list of "further style guide considerations" of questions, irregularities or omissions that have been raised over the last few years, and would make for a good start for this.

The whole time I'm keeping an eye on Python's PEP system and the IETF rules for doing this. We cannot outright copy their processes, but they are definitely influencing the bylaws.

Summary

I feel like the FIG is a great project/organisation/group with a lot of smart people working on/in it. I got the chance to meet many more FIG reps at SunshinePHP, meaning I've met about half of the group now and it's a great crowd.

While I consider the rest of them to be smart as hell, we do have an issue where this thing has kinda grown in a really ad-hoc way, been more successful than probably anyone expected and now we're dealing with the artifacts of that growth and early naivety.

  • Dependencies are a bad idea
  • No "Review" phases existed, where projects could implement standards before use
  • PSR-2 was not implemented by anyone before it was approved, and hardly even still
  • Nobody ever discussed how to deprecate/replace a standard

I'm trying to help solve these issues, better the workflows and processes and help people learn from the mistakes, while the entire time taking flack from a lot of the community who just want to troll the FIG for not being perfect. To those people I feel like saying: do better, or go home. I'm doing what I can to make the situation better, and I'd be really grateful to hear feedback from the rest of the community about how to make the situation better.

Agree, disagree, have alternative ideas, etc, all great. Just keep it positive.

Comments

Gravatar
Trevor Suarez

2014-02-13

Great post, Phil. This definitely clarifies some of the questions I had about future PSR's regarding style.

Gravatar
Tim Fountain

2014-02-13

Great to see progress being made, even if things 'by committee' can end up going slow.

On amendments, hopefully common sense will prevail here. IMHO I can't really see any sensible argument against these providing:

  1. The amendment wouldn't break any existing implementations made against that standard
  2. The PHP-FIG members can agree that the amended section still fits with the spirit of the original

All of your suggestions meet those conditions. Personally I'd favour rewording it to your suggestion of "a current PSR autoloading standard", to future-proof it against a hypothetical third autoloading standard somewhere down the line (you never know).

Gravatar
Ryan Mahoney

2014-02-14

Excellent post. These initiatives make PHP an increasingly better ecosystem with which to develop in. Thank you for your service!

Gravatar
Dave Hulbert

2014-02-14

There's always going to be opposition to progress. The PHP-FIG has already made a huge improvement to the PHP ecosystem - both to framework developers and developers who use that code. Thanks for your part in that process.

Semantic versioning works really well for packages - is that something that's been discussed for PSRs? It doesn't apply as well to specs though. E.g. PSR-0v1 would be the current PSR-0; PSR-0v2 would be the current PSR-4 and PSR-2.x could depend on PSR-1.x.

PS, Thanks for merging my spelling fix pull request - I almost didn't bother as I thought there'd be politics involved :-).

Gravatar
Benjamin Kohl

2014-02-14

I try to write my code up to the PSR-2 standard but I just reviewed the requirements and realized there is one I've definitely not been doing ever and that is adding the space between "function" and the parenthesis for closures. Whoops. I was close! Maybe I overlooked it, but isn't there also supposed to be one space at the end of every file?

Gravatar
Benjamin Kohl

2014-02-14

Correction, I meant one "empty line", not a "space". I knew what I meant but I realized that definitely sounded wrong.

Gravatar
Aleksander Koko

2014-02-15

Great work with the FIG . It has been a revolution so far for PHP . Finally someone puted on rails this language . Keep doing the good work .

Gravatar
Matt Parker

2014-02-16

Yes, good.

  1. Slow is not necessarily bad.
  2. Change is fine, change is the way of the world, deprecation is just what happens. If you don't let things deprecate then you're consigning the whole project to irrelevancy, eventually, which would be a shame. And these are recommendations, not law.
  3. Semantic versioning is a good thing and a nice idea, except that it would feel like it'd give permission for too much change - you could just slip out a new minor point release that means you ought to add or remove a space from something (or whatever). So change is good, but not too often!
  4. One thing I really liked about Promises in js is that, as only a slightly interested onlooker, it felt like the spec was defined by the test suite. There is a specification, obviously, but what defines whether your implementation is compliant is whether it passes the tests. I wonder if something similar would be helpful here? So a PSR-x implementation is compliant if it passes a definitive set of unit tests?

And thanks.

Gravatar
Ben Ramsey

2014-02-20

Why don't we take a queue from the IETF RFC process and, rather than mark things "deprecated," we mark things as "updated by" or "obsoleted by?"

Take RFC 2616, for example: http://tools.ietf.org/html/rfc2616

When you load that, at the top, you see that it has been updated by RFCs 2817, 5785, 6266, and 6585. We can also see that it obsoletes 2068. When the new httpbis drafts are approved, they'll obsolete 2616 and update others (for example: http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26).

Gravatar

2014-02-20

Ben: "Obsoletes" and "Obsoleted By" would definitely be two great terms for this, instead of Suggested and Deprecated. The only difference in this case is semantic, as they achieve the same goal, but you're right that would be more standard.

If the test fails (looks like it wont) then I can change the wording. If it passes I'll ask around if anyone is interested in updating the wording and if they do I'll push a vote. :)

Posting comments after three months has been disabled.