Once upon a time, at a conference, the lead developers from a selection of frameworks sat down in the same room and agreed on some standards for all their projects to use. The aim was to make PHP frameworks and libraries easier to combine for users. That is when php-fig: the PHP Framework Interop Group was born. This group of awesome individuals oversees the PHP Standards Recommendations (PSRs).


The PHP Standard Recommendation (PSR) is a PHP specification published by the PHP Framework Interoperability Group (PHP-FIG). It serves the standardization of programming concepts in PHP. The aim is to enable interoperability of components. The PHP-FIG is formed by several PHP frameworks founders. Dive into this article to learn about different PSRs and how you can adhere to them.

PSR-0 & PSR-4

These describe a specification for auto loading classes from file paths. PSR-0 and PSR-4 are both standards concerning namespaces, class names and file paths. This PSR also describes where to place files that will be autoloaded according to the specification.

Auto loading

Autoloading is a functionality to help developers including  PHP classes automatically without writing cluttered include/require statements everywhere.
In PHP, class's definition is loaded with require or include statements in the files they are being called i.e., prior to using it as shown below. 

include 'Utility/Test Example.php';

$exampleObj = new TestExample();

 

The above approach raises some issues as if we have tens of external classes to be used in a file and we start writing lines of require/include statements right at the beginning of a source file. 

To overcome this issue PHP 5 introduced the magic function __autoload() which is automatically called when your code references a class or interface that hasnā€™t been loaded yet.

void _autoload (string $classname);

Hereā€™s an example of a basic __autoload() implementation: 

<?php

function _autoload($className) {
  
  $filename = 'Utility/ā€™ . $className . '.php';
  
    if  (is_readable($filename))  {

      require $filename;
    }
}

$exampleObj= new TestExample();

The major drawback to the __autoload() function is that you can only provide one autoloader with it. PHP 5.1.2 introduced another autoloading function (spl_autoload_register) for coping with __autoload 's limitation. 

The introduction of spl_autoload_register() gave programmers the ability to create an autoload chain, a series of functions that can be called to try and load a class or interface. 

For example:

<?php

function utilityAutoloader($className) {

  $filename = 'Utility/ā€™  , $className '.php';

  if (is_readable($filename)) {

    require $filename;

  }
}


function functionAutoloader($className) {

  $filename = 'Functions/ā€™   . $className . '.php';

  if (is_readable($filename)) {

    require $filename;

  }
}


spl_autoload_register('utilityAutoloader');

sp1_autoload_register('functionAutoloader');

Autoloading was  such a great idea that every project started to use it. Inevitably everyone created their own version of autoloader as uniform standards were lacking. Clearly, PHP desperately needed a standard for autoloader, which is how PSR-0 was born. The latest accepted autoloader standard is PSR-4. 

PSR-0 (Autoloading Standard)

Overview of PSR-0:

  • A fully-qualified namespace and class must have the following structure 
    \<Vendor Name>\(<Namespace>\)*<Class Name>
  • Each namespace must have a top-level namespace (ā€œVendor Nameā€).
  • Each namespace can have as many sub-namespaces as it wishes.
  • Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system.
  • Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace.
  • The fully-qualified namespace and class are suffixed with .php when loading from the file system.
  • Alphabetic characters in vendor names, namespaces, and class names may be of any combination of lowercase and uppercase.

Examples:

\Doctrine\Common\IsolatedClassLoader =>
/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php

\Symfony\Core\Request =>
/path/to/project/lib/vendor/Symfony/Core/Request.php

PSR-4 (Autoloading Standard)

Overview of PSR-4:

  • The term ā€œclassā€ refers to classes, interfaces, traits, and other similar structures.
  • A fully qualified class name has the following form:
    \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
  • The fully qualified class name MUST have a top-level namespace name, also known as a ā€œvendor namespaceā€.
  • The fully qualified class name MAY have one or more sub-namespace names.
  • The fully qualified class name MUST have a terminating class name.
  • Underscores have no special meaning in any portion of the fully qualified class name.
  • Alphabetic characters in the fully qualified class name MAY be any combination of lowercase and uppercase.
  • All class names MUST be referenced in a case-sensitive fashion.

Example for PSR-4 based Autoloading using Composer:

  • Consider the following directory structure to achieve PSR-4 based autoloading using composer.

psr_image6

  • Create a composer.json file using composer init. If not, you can create one manually now in your projectā€™s root.

    specbee@specbee-HP-ProBook-640-G1: /var/www/html/psr$ touch composer.json
    
  • Set up PSR4 autoloading by editing the composer.json file as shown below:
{

  ā€œautoloadā€ : {

    ā€œpsr-4ā€ : {

      ā€œCodecourse\\ā€™ : ā€œsrc/ā€

    }

  }

}
  • Here, CodeCourse is a vendor name of your application, you can use this name while namespacing files inside of your src directory ,such as:

     namespace CodeCourse\Filters;

    Or

    namespace CodeCourse\Repositories;
    

         etc,

  • And src is your applicationā€™s directory that you want to autoload.
  • Next, open up your terminal and type in the following command to install autoloading files in your project.This will generate the vendor directory and autoload.php file inside of it.
specbee@specbee-HP-ProBook-640-G1:/var/www/html/psr$ composer dump-autoload -0
  • Letā€™s first create a couple of classes inside of the CodeCourse directory.

Create AuthFilters.php inside CodeCourse/Filters

<php
namespace CodeCourse\filters;
class AuthFilters
{
  public function _construct()
  {
    echo ā€œAuthfiltersā€;
  }
}

Create UserRepository.php inside CodeCourse/Repositories

<?php

namespace CodeCourse\Repositories;

class UserRepository
{
  public function _construct()

  {

    echo ā€œHelloā€;

  }
}
  • Finally, create an index.php file to test it out and need to require once the autoload.php file once into your index.php file.
<?php


use CodeCourse\Repositories\UserRepositoru as UserRepository;
use CodeCourse\Filters\AuthFilters as AuthFilters;

require_once_DIR_ .ā€™/vendor/autoload.phpā€™;

$user = new UserRepository ();

$filter= new AuthFilters();

// This echoes ā€œHello AuthFiltersā€

PSR-1 & PSR-2

PSR-1 and PSR-2 are useful for PHP coding standards. PSR-1 mainly focuses on the basic coding standard for PHP whereas PSR-2 is more like an expanded version of PSR-1. PSR-1 lists a set of simple rules for naming conventions and PSR-2 provides a more comprehensive coding style guide. 

PSR-1 (Basic Coding Standard)

Overview of PSR-1:

  • Only <?php or <?= are allowed for PHP tags.
  • Class names must be defined in UpperCamelCase.
  • Class variables must be defined in camelCase.
  • Class constants must be defined in UPPER_SNAKE_CASE.
  • Method names must be defined in camelCase.
  • Files SHOULD either declare symbols (classes, functions, constants, etc.)  or cause side effects(e.g. generate output, change .ini settings, etc.) but SHOULD NOT do both. I.e.,
<?php

include ā€œfile.phpā€;

?>

The above example causes a side effect, i.e., loading a file named ā€œfile.phpā€.

  • Files must be in UTF-8 without BOM(Byte Order Mark).
  • Namespaces and class names must follow the standards in PSR-0 and PSR-4.

Here is an example that illustrates the basic naming conventions for properties, classes, and methods.

<?php
class Classname
{
  public $firstProperty; //Donā€™t declare multiple properties in a single line
       
  public static $StaticProperty;
  
  public function firstMethod()
  {
    //definitionā€¦
  }
}

?>

PSR-2 (Coding Style Guide)

Overview of PSR-2:

  • You must follow the PSR-1 coding standards.
  • 4 spaces must be used for indents. Using tabs is not allowed.
  • There is no limit to line length, but it should be under 120 characters, and best if under 80.
  • There must be one blank line after namespace declaration and there must be one blank line after the block of use declaration.
  • Opening curly braces for classes and methods must go on the next line and closing curly braces must go on the line after the body.
  • Methods and properties must be defined with abstract/final first, followed with public/protected, and finally static keyword.
  • You must not put a newline before curly braces in conditional statements.
  • You must not put any spaces before ( and ) in conditional statements.
  • An example for defining classes:
  • You must open the curly braces on the new line and the extends and the implements keyword must be used in a single line.
<?php

class ClassName extends ParentClass implements InterfaceName

{
  //class definitionā€¦
}

?>

If there are multiple interfaces to implement, then you can write the interface names in the new line as shown below:

<?php

class ClassName extends ParentClass implements

InterfaceName1,

InterfaceName2,
InterfaceName3

{

  //class definition..

}


?>

Example to show how methods are defined in PHP:
While defining the methods, the arguments should be written in the same line. Also, you must not put any whitespaces before commas in arguments, and you must put one whitespace after them.

<?php

class ClassName

{
  public function method($arg1, $arg2)
  {

    //definitionā€¦

  }
}

?>

If there are many number of arguments, then they can be written in newline one after the other:

<?php
class ClassName
{
  public function method(
  arg1,
  arg2,
  arg3)   {
    //definitionā€¦
  }
}

?>

When defining methods, you must have either one of public/protected/private and abstract/final. The visibility modes come after the abstract/final keyword, if used. static is the last modifier.

<?php
class ClassName
{
  abstract public function abstractMethod();
  final public static function staticMethod()
  {
    //definitionā€¦
  }
}

?>

Conditional Statements

  • You must put one whitespace before (
  • You must not put any whitespaces after (
  • You must not put any whitespaces before )
  • You must put one whitespace after )
  • use elseif rather than else if.

Example to show the difference between elseif and else if:
Interpretation of elseif:

<?php

if ($condition1) {
  //ā€¦
}  elseif  ($condition2) {
  //ā€¦
} else {
  //ā€¦
}

?>

Interpretation of else if:

<?php

if ($condition1) {
  //ā€¦
} else {
if (condition2) {
  //ā€¦
  }
}

?>

For the switch statements, 

  • The curly braces must be opened in the same line where the switch statement is written.
  • The case body must be indented once from the case and the case must be indented once from the switch.
  • Use no break when break is not needed.
  • You can also use return instead of break.

Example:

<?php
switch($condition) {
case 0:
   echo ā€˜Use a breakā€™ ;
   break;
case1:
   echo ā€˜If you are not using break; then write no break as a commentā€™ ;
// no break
case 2:
   echo ā€˜Use return instead of breakā€™ ;
return;
default:
echo ā€˜Defaultā€™;
break;

}
?>

Huge shoutout to Samvada Jain for her contributions to this article.

Final Thoughts

In a project that is incorporated with various packages, it can be a mess if each individual uses a different coding standards. This is the reason why PSR was designed. In total, there are over 20 PSRs that are designed and each PSR is suggested by members and voted according to an established protocol to act consistently and in line with their agreed upon processes.

Our expertise in PHP stems from our focus on Drupal - An enterprise CMS built using PHP. If you are looking to develop a custom module for Drupal or any other Drupal development services, talk to us today!

 
 
Contact us

LET'S DISCUSS YOUR IDEAS. 
WE'D LOVE TO HEAR FROM YOU.

CONTACT US