PSR-Huh?

If you're an avid PHP developer, it's quite likely that you've come across the abbreviation, PSR, which stands for "PHP Standards Recommendation." At the time of this writing, there are four of them: PSR-0 to PSR-3. Let's take a look at what these are, and why you should care (and participate).


A Brief History

PHP has never truly had a uniform standard for writing code. Those who maintain various codebases commit time to writing their own naming conventions and coding style guidelines. Some of these developers choose to inherit a well-documented standard, such as PEAR or Zend Framework; yet others choose to write standards completely from scratch.


The Framework Interoperability Group

Do not hesitate to open a new topic in the mailing list.

At the php|tek conference in 2009, people representing various projects discussed their options for working between projects. It surely comes as no surprise that sticking to a set of standards between codebases was the main agenda item.

Until recently, they labeled themselves as the "PHP Standards Group", but now, they operate under the umbrella, Framework Interoperability Group (FIG). As they felt, the former didn't accurately describe the group's intentions. Even though the name of this group explicitly refers to frameworks, developers representing all sorts of projects have been accepted as voting members.

The FIG intends to host a cross-section of the PHP ecosystem, not exclusively framework developers. For example, the Symfony, Lithium and CakePHP frameworks each have a representative as a voting member, but the same goes for PyroCMS, phpDocumentor, and even Composer.

The voting members can start or participate in votes, however, anyone else (including you!) can become a PHP-FIG community member by subscribing to the PHP-FIG mailing list.

This mailing list is where discussions, votes, suggestions and feedback take place.

The Goal

The goal of the FIG is to create a dialogue between project representatives, with the aim of finding ways to work together (interoperability). At the time of this writing, that dialogue has spawned four PHP Standards Recommendations: PSR-0 to PSR-3.

Those recommendations are free and can be adopted by anyone, though no one is obligated to do so. In fact, voting members are not required to implement any of the PSRs in the projects that they represent!


PSR-0: Autoloader Standard

PSR-0 is a huge step forward for reusable code.

Remember how you used to specify many require statements to reference all of the classes you require? Thankfully, this pattern changed with PHP 5's magic __autoload() function. PHP 5.1.2 made autoloading even better by introducing spl_autoload(), which allows you to register a chain of autoloading functions with spl_autoload_register().

No matter how good the autoloading functionality is, it does not define how to implement it with existing codebases. For example, library X might approach the directory and classname structure differently than library Y, but you might want to use both!

Writing a proper autoloader that knows where to look for all possible fully-qualified names, as well as test all file extensions (.class.php, inc.php, .php etc) will quickly become a mess. Without a standard to define how to name classes and where to place them, autoloader interoperability would still be a pipe dream.

Meet PSR-0. A standard recommendation that describes "the mandatory requirements that must be adhered to for autoloader interoperability."

PSR-0 is a huge step forward for reusable code. If a project follows the PSR-0 standard and its components are loosely coupled, you can simply take those components, place them within a 'vendor' directory, and use a PSR-0 compliant autoloader to include those components. Or, even better, let Composer do that for you!

For example, this is exactly what Laravel does with two Symfony Components (Console and HttpFoundation).

The FIG has an example implementation of a PSR-0 compliant autoloader function that can be registered to spl_autoload_register(), but you are free to use any of the more flexible implementations, such as the decoupled Symfony ClassLoader or Composer's autoloader.


PSR-1: Basic Coding Standard

PSR-1 focuses on a basic coding standard.

There was a lengthy period of low-activity in the FIG after PSR-0's acceptance. In fact, it took a good year and a half before the PSR-1 and PSR-2 documents were approved.

PSR-1 focuses on a basic coding standard. It refrains from being too detailed, and does so by limiting itself to a set of ground rules to "ensure a high level of technical interoperability between shared PHP code".

  • Only use the <?php and <?= tags.
  • Only use UTF-8 without BOM for PHP code.
  • Separate side-effects (generate output, access a database etc.) and declarations.
  • Enforce PSR-0.
  • Class names must be defined in StudlyCaps.
  • Class constants must be defined in upper case with underscore separators.
  • Method names must be defined in camelCase.

The ground rules focus on naming conventions and file structure. This ensures that all shared PHP code behaves and looks the same way at a high level. Imagine an application that uses numerous third-party components, and they all use different naming conventions and character encodings. That would be a mess!


PSR-2: Coding Style Guide

PSR-2's purpose is to have a single style guide for PHP code that results in uniformly formatted shared code.

PSR-2 extends and expands PSR-1's basic coding standards. Its purpose is to have a single style guide for PHP code that results in uniformly formatted shared code.

The coding style guide's rules were decided upon after an extensive survey given to the FIG voting members.

The rules in PSR-2, agreed upon by the voting members, do not necessarily reflect the preferences of every PHP developer. Since the FIG's beginning, however, the PHP-FIG has stated that their recommendations have always been for the FIG itself; others willing to adopt the recommendations is a positive outcome.

The full PSR-2 specification can be found in the fig-standards repository. Be sure to give it a read.

In an ideal world, every PHP project would adopt the recommendations found in PSR-1 and PSR-2. However, due to taste (i.e. "Naming convention x looks better than y!", "Tabs over spaces!") and historical segmentation between various coding styles, there have only been a sparse amount of PHP projects adopting PSR-1 and PSR-2 in its entirety.


PSR-3: Logger Interface

PSR-3 describes a shared logging interface.

PHP Standard Recommendation #3 is the most recent addition to the accepted FIG-standards. It was accepted on December 27, 2012 with an impressive vote count of 18 to 0 (8 voting members did not cast a vote).

PSR-3 describes a shared logging interface, incorporating the eight Syslog levels of The Syslog Protocol (RFC 5424): debug, info, notice, warning, error, critical, alert and emergency.

Those eight Syslog levels are defined as method names, which accept two parameters: a string with a log $message and an optional $context array with additional data that does not fit well in the former string. Implementers may then replace placeholders in $message with values from $context.

A shared interface standard, like PSR-3, results in frameworks, libraries and other applications being able to type hint on that shared interface, allowing developers to choose a preferred implementation.

In other words: if a logging component is known to adhere to PSR-3, it can simply be swapped with a different PSR-3 compliant logging component. This assures maximum interoperability between calls to logger implementations.

Monolog recently implemented PSR-3. It's therefore known to implement the Psr\Log\LoggerInterface and its associated guidelines found in the PSR-3 document.


Criticism

The PHP-FIG is doing a great job of centralizing PHP standards.

Some people say that the PSRs go too far to define a global set of standards to define a coding style - something that is more subjective than objective. Others feel that a shared interface is too specific and not flexible. But criticism comes naturally with any standard initiative. People don't like how identifiers are supposed to be named, which indentation is used, or how the standards are formed.

Most of the criticism and reflection takes place from the sideline, after the standards are accepted - even though the standards form in the mailing list (which is open for everyone to join in and leave feedback, comments or suggestions). Do not hesitate to open a new topic in the mailing list, if you think you have something valuable to add.

It's also important to keep in mind that it's not the specific combination of rules, which contribute to the benefit of the recommended standards, but rather having one consistent set of rules which are shared among various codebases.

By everyone shirking their own preferences, we have one consistent style from the outside-in, meaning I can use ANY package - not just whichever happens to be camelCase.

- Phil Sturgeon in the PHP-FIG mailing list


The Future

The FIG intends to host a cross-section of the PHP ecosystem, not only framework developers.

With a growing number of influential voting members and four accepted standards, the FIG is certainly gaining more traction in the PHP community. PSR-0 already has widespread usage, and hopefully PSR-1 and PSR-2 will follow suit to achieve more uniformity in shared PHP code.

With the shared interface defined in PSR-3, the Framework Interoperability Group took a new turn in recommending standards. They are still heading in that direction, as the contents of new shared interfaces are being discussed on the mailing list.

Currently there is an interesting discussion about the proposal of an HTTP Message Package, which holds shared interfaces for implementing an HTTP client. There are also various discussions proposing a shared Cache interface; but, as of now, it seems to be on low-activity.

No matter what the outcome of those proposals will be, the PHP-FIG is doing a great job of centralizing PHP standards. They are without a doubt influencing the PHP ecosphere in a positive manner, and hopefully their efforts will obtain a more prominent place in the PHP programming language.

Remember: currently, they still operate under the name of the Framework Interoperability Group, and have no intentions whatsoever to tell you - Joe the Programmer - how to build your applications. They merely recommend a set of standards that anyone can adopt.

Tags:

Comments

Related Articles