Let’s begin at the beginning. Once upon a time, at a conference, the lead developers from a selection of frameworks sat down in the same room (they are better at it nowadays, at the time I might not have believed it had I not been there) and agreed some standards for all their projects to use. The aim is to make PHP frameworks and libraries easier to combine for users, and so it was that php-fig: the PHP Framework Interop Group was born. This group of awesome individuals oversee the PHP Standards Recommendations (PSRs).
Zero is for Autoloading
It’s zero because it’s the building block for all other things. That first meeting saw discussion on how the introduction of namespaces in PHP 5.3 could be adopted in a similar pattern by many different frameworks. This has developed into PSR-0 which is a standard autoloader. There isn’t much to add here, except to say:
- The autoloader isn’t the point. The point is that everyone uses naming and namespaces so consistently that this autoloader can find everyone’s stuff, making it easy to combine tools in a single application
- This turned out later to give us enough standard-ness for Composer to become possible – Composer is a whole other blog post though (and it’s already been written by someone else)
One and Two are for Coding Standards
Someone will tell me that these are not actually the same thing, but to those of us standing in userland, they are at least very closely related! PSR-1 lays out some very basic but very wise coding standards. They are minimal, clean and useful. If you’ve ever had an argument about the correct capitalisation of a method name, just use this. Importantly, one of the requirements of PSR-1 is that all code must conform to PSR-0, so PSR-0 is a pre-requisite of PSR-1.
PSR-2 claims to be a “coding style guide” rather than a “coding standard” but honestly, I think you need this too. This aims to get beyond the functional basics in PSR-1 and to introduce some readability elements. As developers, we know what a codebase with unfamiliar formatting does to our brain and while I’m sure there were many flamewars in the making of this standard, and not all of it is to my taste, it’s good. These standards are now supported by PHP CodeSniffer so they’re very easy to adopt into your project (they were introduced in PHPCS 1.4.0 so you may need to install from PEAR if you have a version older than that). Exactly as before, PSR-2 has PSR-1 as a pre-requisite – code conforming to PSR-2 must first conform to PSR-1.
Three is for Logging
At this point, I’m not sure how long the numerical naming can work for but that doesn’t detract from the PSR-3 standard. This one is interesting because it contains some PHP code; the code for the interfaces that all compliant logging libraries will implement. With this standard becoming increasingly widely adopted (I knew about it but only saw the detail when working with Monolog recently), it will be easy to have different logging tools, either standalone libraries or modules from frameworks, being used interchangeably in your application. All new logging tools will implement this standard and you’ll be able to pick, choose, then change your mind at a later point, all as you wish.
Standards and PHP
Standards and PHP are a bit of a funny mix, we’ve a long history of Not-Invented-Here syndrome, as many PHP frameworks as there are PHP developers, and generally 46 different ways of skinning any given cat. That said, I hope this post has given you an idea of what all those codenames were actually for and why the average developer on the street might care about what’s coming out of php-fig.
Very interesting read. Nice intro to PSRs as well.
Nice summary, PSR-1/2 seem like the same thing to me too!
This is a nice tool for making your code conform to these standards: http://cs.sensiolabs.org/. CodeSniffer identifies the issues, this tool fixes them automatically for you.
This a good writeup, thanks for doing it. A few points to add:
PSR-1 and PSR-2 started off as the same thing, but they became split to allow projects willing to take part in everything PSR-1 has to offer, without having to switch their tabs to spaces, or put their brackets on certain lines, etc. This is very important, as it allows the crucial parts (make sure its UTF-8, dont use ?> and get junk white-space, etc) to be implemented.
Another benefit is PSR-1 is allows everything on the outside to look identical. I can USE any package from anyone following PSR-1 and from inside my application (but outside their component) it is all consistent (camelCase). But inside their component, I probably don’t care what they do. This works nicely for PyroCMS, which is itself transitioning to PSR-1 and uses PSR-1 components. If component developers want to adopt PSR-1 and not PSR-2 then WHOOP whatever, but I still get all the functional compatibility & non-destructive benefits. :)
As for the numerical numbering, do not apply too much meaning to them. They are just incrementing IDs and have no other meaning, it just so happens the first few happened to be related. PSR-4 could be a Cache interface and PSR-5 may well be a new and improved autoloader.
I’m putting together a workflow for the FIG which is very similar to PEP (for Python) where their PEPs may be accepted or rejected but still have a number, so in the above example PSR-4 and PSR-6 might exist, but PSR-5 could well be rejected for a while (or forever) then get revived later down the road. It’s just a name, they’re not related!
But on the whole, this is great.