Why I never implemented PSR-12

Last week I finally decided to update most of my OSS to get them ready for PHP8. In doing so I locked my repo to github since travis is about to drop open source CI/CD integration and I took the time to update static analysis tools but when it came to my coding style rules, I did nothing. Yes I left it as it has always been. My current set of rules are based on PSR-2 with a superset of rules that I like. I did not even bother to check if the code was still in line with the replacing PSR, which is PSR-12 and I will try to tell you why.

Back in the days when PSR-1 and PSR-2 was voted on their was a huge adoption rates. The reason was simple it was backed by all the major frameworks at that time and even despite the space vs tab controversy there was not so much discussion. The contentious rules where either dropped, added in the separate PSR-2 recommendation or left to the discretion of users.

Fast forward to PSR-12 which superseded PSR-2 by fixing some of its bugs/oversights and added new rules. The people behind PSR-12 did a great job. Some may disagree on some of the new rules but having followed how the recommendation came to be accepted, the authors deserve a lot of respect and consideration. Having said that, in my mind, they made 2 big mistakes that made me come to the conclusion that I should not care about PSR-12.

The first mistake was that in opposition to PSR-2 which was build on experiences, statistic usage in all main frameworks using older recommendation as basis (PEAR, Zend coding style to name but a few), PSR-12 was build on assumption meaning that some rules where created while the feature were not already available, PSR-12 was build to go along with PHP7 (I am oversimplifying here). Either way, people were not given proper time to really assess if the rule was exactly how people would end up using the new syntax.

The second mistake is the PSR acceptance flow. By the time PSR-12 was accepted, PHP, the project, had already announced/implemented/discussed new syntaxes for PHP8 making PSR-12 dead on arrival as it was certified with never tested practices and was already outdated because new syntaxes were not taken into account. Yet, it was still advertised as covering new features which makes the whole exercise miss its target or ambition. Furthermore, the current workflow means that to add all those new PHP syntaxes, like how to properly style the new match expression or attributes, we need a brand new PSR to replace PSR-12. In the meantime, those syntaxes are not covered by any PSR, so frameworks, library maintainers and users are left choosing whatever they prefer. Which ultimately will lead to going back to a pre-PSR world where everyone will practically do whatever he/she thinks is the correct way of writing those new syntaxes.

Thankfully we don’t need to go that far back. We now have mature tools to enforce coding style on project. Tools like php-cs-fixer can be hooked to your CI/CD pipeline and supports PSR-2/PSR-12 rules as basis but are not limited to them. Those tools can also be easily extended to support new rules as new syntaxes and features are added to the language. Last but not least they can evolve faster than the current recommendations.

Having said that, we still need some kind of common ground just for the sake of readability between projects. And while I’m not a fan of every recommendation in PSR-12, PSR recommendations are still the de-facto based coding standard for the PHP community. So a way forward should be to make PSR regarding coding style evolve faster and a good way to do it would be to make them rely on a living standard document just like the WHATWG group did for HTML.
Also it would be an added benefit to associate CS tools maintainers to that process so we as a community can benefit from their experiences and together build better rules and improve PHP coding style rules just like PHPStan/Psalm are driving user-land static analysis forward currently.

Whatever process is chosen do keep in mind that projects will always add specific rules based on their usage/experience. The goal has never been to strictly follow any guideline but to use them as a foundation and adapt them to our codebase accordingly.

3 thoughts on “Why I never implemented PSR-12

  1. IMHO, all the PSR-* are far too inconsistent from a *logical* standpoint. I don’t care about statistics so much as about *consistency*.

    Just some points that annoy me most…

    I find no rhyme nor reason, why { at some points MUST BE to be on its very own line,
    while on other, logically not at all different points it MUST NOT BE on its own line at all.
    “{} is a block, and it is bound to the line where the { starts, for these 4 cases.”
    “{} is a block, and it is bound to the line before the { starts, for these other 7 cases.”
    Eh, no, thanks. (In general, the “own line” just wastes a line.)

    Forbidding to group use-statements logically? I prefer 1. system use, 2. framework use, 3. other, foreign plugins use, 4. own plugin use, and each block neatly separated by an empty line. But oh, no, PSR-12 says, you MUST NOT put empty lines into your use block.
    Screw “readability at a glance”!

    Another in-general thing: I think it should be a global rule, that you can and SHOULD add empty lines when a logical group of lines fits well together (whenever there’s more than one logical group in a block).

    And then the age-old tabs vs. space… that’s just pure noise. In the days past, there was a simple convention to encode the “official” way for a file at the bottom, and better editors could dynamically adapt to the user’s preferences while editing. What happened to that? Gone with the wind…

    I must admit though, I still carry an old inconsistency with me: space or no space before (. I just can’t get myself to do a spaceless if(…, which would be truly consistent with while(…, for(…, do(…,with(…, and *any* *other* statement that encases a statement block. 😐

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.