PHP Standards Recomendations and Symfony

Richard Melo

@allucardster

About me

  • System Engineer
  • 8+ years experience
  • Fullstack Developer
  • SUDO co-founder

Agenda

  • Intro
  • What is PSR?
  • PSR and Symfony

"if else" statement in PHP

if ($foo == 1) {
    echo "Foo is one";
} else if ($foo == 2) {
    echo "Foo is two";
} else {
    echo "Foo is something else";
}
if ($foo == 1)
    echo "Foo is one";
else if ($foo == 2)
    echo "Foo is two";
else
    echo "Foo is something else";
if ($foo == 1) {
    echo "Foo is one";
}
elseif ($foo == 2) {
    echo "Foo is two";
}
elseif ($foo == 3) {
    echo "Foo is three";
}
else {
    echo "Foo is something else";
}
if ($foo == 1) {
    echo "Foo is one";
}
elseif ($foo == 2)
    echo "Foo is two";
else if ($foo == 3) {
    $message = "Foo is three";
    echo $message;
}
else
    echo "Foo is something else";
if ($foo == 1):
    echo "Foo is one";
elseif ($foo == 2):
    echo "Foo is two";
elseif ($foo == 3):
    $message = "Foo is three";
    echo $message;
else
    echo "Foo is something else";
endif;

Why?

"Alternate syntax makes the code only clearer and easier to read"

http://php.net/manual/en/control-structures.alternative-syntax.php#89860

But...

It's a partial truth

Let's think into a...

php template

<div>
    <?php if ($foo == 1) { ?>
        Foo is one
    <? } ?>
    <?php elseif ($foo == 2) { ?>
        Foo is two
    <? } ?>
    <?php elseif ($foo == 3) { ?>
        Foo is three
    <? } ?>
    <?php else { ?>
        Foo is something else
    <? } ?>
</div>
<div>
    <?php if ($foo == 1): ?>
        Foo is one
    <?php elseif ($foo == 2): ?>
        Foo is two
    <?php elseif ($foo == 3): { ?>
        Foo is three
    <?php else: ?>
        Foo is something else
    <? endif; ?>
</div>

That it's ok for php templates

what about php code?

  • Even clearer?
  • Easier to read?

Maybe...

Maybe not...

Who cares...

it's my own code style and practices

For languages like php that allow to...

"FOLLOW YOUR INSPIRATION"

It's pretty important write your code well

PSR

"PHP Standard Recommendation, it's an specification created to standarize the programing concepts, code style and documentation around PHP "

PSR

  • Created in 2009 by PHP-FIG
  • Frameworks developer recommendations
  • It pretends establish a single style guide for PHP to uniform the code and allow share it
  • It's not a way to tell you how to build your app

Autoloading

Interfaces

Coding styles

PSR-4: Improved Autoloading

PSR-3: Logger Interface

PSR-6: Caching Interface

PSR-7: HTTP Message Interface

PSR-1: Basic Coding Standards

PSR-2: Coding Style Guide

PSR-0: Autoloading Standard (Deprecated)

  • PSR-0: Autoloading Standard (Deprecated)
  • PSR-1: Basic Coding Standard
  • PSR-2: Coding Style Guide
  • PSR-4: Improved Autoloading

PSR-0: Autoloading Standard (Deprecated)

"Mandatory requirements that must be adhered to for autoloader interoperability"

http://www.php-fig.org/psr/psr-0/

  • A fully-qualified namespace and class must have the following structure:

<Vendor Name>\(<Namespace>\)*<Class Name>

//example:

\Symfony\Core\Request
  • 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.
\Symfony\Core\Request

//in the autoloader will be read as:

/Symfony/Core/Request
  • The fully-qualified namespace and class are suffixed with .php when loading from the file system.
\Symfony\Core\Request

//in the autoloader will be read as:

/Symfony/Core/Request.php
  • Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace.
\DAIS\Manager\Custom_MessageManager

//in the autoloader will be read:

/DAIS/Manager/Custom/MessageManager.php
  • Alphabetic characters in vendor names, namespaces, and class names may be of any combination of lower case and upper case.
\LoreM\IpSUM\Dolor

//in the autoloader will be readed as:

/LoreM/IpSUM/Dolor.php

PSR-1: Basic Coding Standard

"Define what be considered the standard coding elements that are required to ensure a high level of technical interoperability between shared PHP code."

http://www.php-fig.org/psr/psr-1/

  • Files MUST use only <?php and <?= tags. it MUST NOT use the other tag variations.
//----------------------------------
// Use this:
//----------------------------------

<?php
    //The PHP code lives here :)
?>

<?="Print this" ?>

//----------------------------------
// Never use this ASP tags:
//----------------------------------

<%
    //The PHP code may live here before PHP 7.0
%>

<%="Print this only before PHP 7.0" %>

<script language="php">
    //The PHP code may live here before PHP 7.0
</script>
  • 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.
<?php
// side effect: change ini settings
ini_set('error_reporting', E_ALL);

// side effect: loads a file
include "file.php";

// side effect: generates output
echo "<html>\n";

// declaration
function foo()
{
    // function body
}
  • Class names MUST be declared in StudlyCaps and each class is in a file by itself
<?php

namespace AppBundle\Controller;

class myDefaultController
{
    //...
}

class MyException extends \Exception
{
    //...
}
  • Class constants MUST be declared in all upper case with underscore separators
  • Method names MUST be declared in camelCase
<?php
namespace Vendor\Model;

class Foo
{
    const VERSION = '1.0';
    const DATE_APPROVED = '2012-06-01';
}
<?php
namespace Vendor\Model;

class Foo
{
    public function loremIpsumDolor()
    {
        //...
    }
}

PSR-2: Coding Style Guide

"The intent of this guide is to reduce cognitive friction when scanning code from different authors. It does so by enumerating a shared set of rules and expectations about how to format PHP code"

http://www.php-fig.org/psr/psr-2/

Files

  • All PHP files MUST end with a single blank line.

  • The closing ?> tag MUST be omitted from files containing only PHP.

<?php

namespace Foo\Bar

class Baz
{
    //...
}

?>
<?php

namespace Foo\Bar

class Baz
{
    //...
}

Lines

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable, \Serializable
{
    public function myLongNameMethod($longAttributeName1, $longAttributeName2, $attr3)
    {
    }
}
<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements 
    \ArrayAccess,
    \Countable,
    \Serializable
{
    public function myLongNameMethod(
        $longAttributeName1,
        $longAttributeName2,
        $attr3
    ) {
        //...
    }
}

Lines

<?php

namespace Foo\Bar

class Baz
{
    public function init()
    {
        $qux = 1;


        $quux = 1;
        $corge = [$qux, $quux]

        echo "<pre>"; print_r($corge); echo "</pre>";

        return $corge;
    }
}
<?php

namespace Foo\Bar

class Baz
{
    public function init()
    {
        $qux = 1;
        $quux = 1;
        $corge = [$qux, $quux]

        echo "<pre>";
        print_r($corge);
        echo "</pre>";

        return $corge;
    }
}

Identing

  • Code MUST use an indent of 4 spaces, and MUST NOT use tabs for indenting.

  • Don't mix tabs and spaces

<?php

namespace Foo\Bar

class Baz
{
  $a = 'Lorem';
        $b = 'dolor';
    $c = $a . ' ' . $b;
    
    return $c
}
<?php

namespace Foo\Bar

class Baz
{
    $a = 'Lorem';
    $b = 'dolor';
    $c = $a . ' ' . $b;
    
    return $c
}

Keywords and True/False/Null

  • PHP keywords MUST be in lower case.
  • The PHP constants true, false, and null MUST be in lower case.
$foo = true; // please don't use TRUE

$bar = false; // please don't use FALSE

$baz = null; // please don't use NULL

// Keyworkds:

throw \Exception("Lorem ipsum dolor");

// instead

THROW \Exception("Lorem ipsum dolor");

Namespaces and "use" declarations

<?php
namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...
<?php
namespace Vendor\Package;

use FooClass,
    BarClass as Bar,
    OtherVendor\OtherPackage\BazClass;

// ... additional PHP code ...
<?php

namespace Vendor\Package;

//...

Common style

Classes

<?php

namespace Vendor\Package;

use BarClass as Bar;
use QuxInterface as Qux;

class Foo extends Bar implements Qux {
    //...
}
<?php

namespace Vendor\Package;

use BarClass as Bar;
use QuxInterface as Qux;

class Foo extends Bar implements Qux
{
    //...
}

Properties

<?php

class Foo
{
    public $bar, $baz;

    $_qux;
    
    static $_quux, $_corge; 
}
<?php

class Foo
{
    public $bar;

    public $baz;

    private $qux;

    private static $quux;

    private static $corge;
}

Methods

<?php

class Foo
{
    function _bar ( $a , $b ) {
        //...
    }
}
<?php

class Foo
{
    private function bar($a, $b)
    {
        //...
    }
}

Method calls

<?php

bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
<?php

bar ( );
$foo -> bar( $arg1 );
Foo::bar( $arg2, $arg3 );

$foo->bar($longArgument, $longerArgument, $muchLongerArgument, $muchLongerArgument2, $muchLongerArgument3);

abstract, final, and static

  • When present, the abstract and final declarations MUST precede the visibility declaration.
  • When present, the static declaration MUST come after the visibility declaration.
<?php
namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}

Control Structures

$arr = [0,1,2,3];

foreach( $arr as $key => $value )
{
    echo "Key $key : $value";
}
$arr = [0,1,2,3];

foreach ($arr as $key => $value) {
    echo "Key $key : $value";
}

 if, elseif, else

  • The keyword elseif SHOULD be used instead of else if so that all control keywords look like single words.
<?php
if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}

switch, case

<?php
switch ($expr) {
    case 0:
        echo 'First case, with a break';
        break;
    case 1:
        echo 'Second case, which falls through';
        // no break
    case 2:
    case 3:
    case 4:
        echo 'Third case, return instead of break';
        return;
    default:
        echo 'Default case';
        break;
}

while, do while

<?php
while ($expr) {
    // structure body
}

<?php
do {
    // structure body;
} while ($expr);

for, foreach

<?php
for ($i = 0; $i < 10; $i++) {
    // for body
}

foreach ($iterable as $key => $value) {
    // foreach body
}

try, catch

<?php
try {
    // try body
} catch (FirstExceptionType $e) {
    // catch body
} catch (OtherExceptionType $e) {
    // catch body
} catch (\Exception $e) {
    // default catch body
}

Closures

<?php
$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};

$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);

PSR-4: Coding Style Guide

"Specification for autoloading classes, interoperable and can be used in addition with PSR-0"

http://www.php-fig.org/psr/psr-4/

// PSR-0
vendor/
    vendor_name/
        package_name/
            src/
                Vendor_Name/
                    Package_Name/
                        ClassName.php       # Vendor_Name\Package_Name\ClassName
            tests/
                Vendor_Name/
                    Package_Name/
                        ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest
// PSR-4
vendor/
    vendor_name/
        package_name/
            src/
                ClassName.php       # Vendor_Name\Package_Name\ClassName
            tests/
                ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

Thank you!

PHP Standards Recommendations and Symfony

By Richard Andres Melo Carrillo

PHP Standards Recommendations and Symfony

A brief description about the PSR coding standards followed by Symfony

  • 1,066