THE STATE OF PHP

Composer, PSR, Frameworks and more

Juan Manuel Torres/@onema
Eric Van Joh
nson/@shocm

FOLLOW ALONG:
http://slides.com/onema/the-state-of-php/live

CODE ALONG:
http://3V4L.org/

Juan Manuel Torres

@onema

Born and raised in Bogotá Colombia

30 largest cities in the world, 7 Mill, 8612 ft, 58 °F

Software Engineer

MS Computer Science SDSU, 5+ years of experience


PHP and me

Started using PHP in 2001

Eric Van Johnson

PHP developer, architect and organizer of SDPHP


@shocm




TO PREVENT YOU FROM FALLING ASLEEP

FOLLOW ALONG:
http://slides.com/onema/the-state-of-php/live
CODE ALONG:
http://3V4L.org/


FRAMEWORKS



"Standing on the shoulder of giants"

ON THE SHOULDER OF 

GIANTS


Using established frameworks leverages the power of the community for stability, enhancements, fixes, and support. “Standing on the shoulder of giants”
Frameworks speed up your development process by giving you a strong codebase to build from. Typically frameworks have defined coding standards and approach to development. This can typically be one of the larger challenges when using a new framework. 
I usually categories frameworks in one of three groups.

MICRO FRAMEWORKS

Micro Frameworks: 
Micro Frameworks come with some very core functionality such as some sort on database interface, router, and a way to handle templating. Usually these Micro Frameworks can be extended out to full fledge frameworks.  

One big advantage to a Micro Framework is that they can often be integrated into an existing application with little effort. And Micro Frameworks usually don’t require a lot of effort to pick up and start working with. 

Some examples of a micro framework would be Silex (baby brother of Symfony), Fat-Free, and Slim.

FULL FLEDGE FRAMEWORK 

OR GENERAL FRAMEWORK

The general PHP Framework has a full development practice associated with it. Many adhere to a Model-View-Controller (MVC) approach. Unlike Micro Frameworks, a general Framework will come with a host of functionality for things like JSON or handling Files and typically will be packaged with their own templating engine. It’s typically more difficult to “integrate” a full fledge Framework into an existing application, These frameworks tend to need to have the application developed within them. 
Because of this, these frameworks can take a little effort to understand. Especially if you struggle getting your head around some of the core development approaches such as MVC.
Examples of General Frameworks would be Laravel, CakePHP, Yii, FuelPHP, and CodeIgniter.

ENTERPRISE FRAMEWORKS

Enterprise Frameworks are designed with Business Logic in mind and have a strong focus on performance and optimization. Heavy in libraries and interfaces these frameworks can be a lot to take on and learn. The biggest advantage of Enterprise Frameworks is that there is commercial support for them. Many have well defined training tracks and certification processes. 

Most Enterprise Frameworks are Open Source and can be used for free but having a Company “own” the project means there can be one trusted source for things like patches.

Examples of Enterprise Frameworks would be Zend Framework 2 and Symfony. 

ADVANCED             FEATURES


NAMESPACES

Introduced in PHP 5.3, Namespaces help to bring logic to the chaos of 3rd party libraries. 

PHP being a little late to the party with Namespaces as many other languages already use them. Namespaces allows you to define multiple methods with the same names. 

EXAMPLE

class User{} 
 To implement you would do something like this

$user = new User();


The problems 

  • A class like User very common 
  • A 3rd party library can cause these sorts of naming conflicts

SOLUTION

Namespaces help to fix that. Let’s say we develop, or deploy, a library for GeekGirl which also has the method “User”. Using Namespaces we might introduce that like this. 

First we would  create our namespace :
<?phpnamespace GeekGirl;

class User{  // GeekGirl User Code}

IMPLEMENT


Now that we have a GeekGirl Namespace defined,
we can use it in our code
by addressing the Namespace itself  


<?php

$user = new GeekGirl\User();


WORKING 
INSIDE A NAMESPACE

When you define a namespace you are working in, then all methods are relative to that name space. But you still have access to the Global namespace.
namespace GeekGirl;

$gg_user = new User(); // User Class in the GeekGirl namespace 
$user = new \User(); // User class from the Global namespace 
 

This means you can also address methods in other libraries. 
namespace GeekGirl;

$user = new \SDConference\User(); 

INCLUDE
AND ALIAS NAMESPACES

There is also a shortcut for referencing these hierarchical namespaces if you plan on implementing them more than once. You can use the ‘use’ command
namespace GeekGirl;
use SDConference\User;

$user = new User(); // Using User method from SDConference
We can also give the method we are importing an alias with the ‘as’ keyword. So for example we can do something like  

namespace GeekGirl;
use SDConference\User as SdConfUser;

$user = new User(); // GeekGirl Namespace
$sd_user = new SdConfUser(); // SDConference 

TRAITS

A trait is like a abstract class but can not be instantiated on its own. Traits are a sort of workaround for PHP's
lack of support for multiple inheritance. 
trait Magic {
    /** 
     * A block of code that does a lot of work
     * need by several other classes 
     */
    public function foo() {}
}

class Reader extends BaseReader {
    use Magic;
}
class Writer {
    use Magic;
} 

MULTIPLE TRAIT IMPORTS

EXAMPLE

trait Hello {
    function sayHello() {
        return "Hello";
    }
}
trait World {
    function sayWorld() {
        return "World";
    }
}
class MyWorld {
    use Hello, World;
}
 
$world = new MyWorld();
echo $world->sayHello() . " " . $world->sayWorld(); //Hello World

ANONYMOUS FUNCTIONS

In computer programming, an anonymous function is a function definition that is not bound to an identifier.
- Wikipedia

function doMath(callable $function, $a, $b)
{
    return $function($a, $b);
}

doMath(function($a, $b) { return $a * $b; }, 9, 2); // 18

LAMBDAS

Lambda is an anonymous function that can be stored in  a variable and passed as an argument
function sum ($a, $b)
{
    return $a + $b;
}

$division = function($a, $b)
{
    return $a/$b;
};

function doMath(Closure $function, $a, $b)
{
    return $function($a, $b);
}

doMath($division, 9, 3); // 3


CLOSURES

A closure is a lambda function that is aware of its surrounding context 
- Fabien Potencier

$division = function($a, $b)
{
    return $a/$b;
};

function doMath(Closure $function, $a, $b)
{
    $result = $function($a, $b);
    return function() use ($result) {echo $result;};
}

$callback = doMath($division, 9, 3);
$callback(); // 3

EXAMPLE


$division = function($a, $b)
{
    return $a/$b;
};

function doMath(Closure $function, $a, $b)
{
    $result = $function($a, $b);
    return function() use ($result) {echo $result;};
}

$callback = doMath($division, 9, 3);
$callback(); // 3

$callback = doMath(function($a, $b) { return $a * $b; }, 9, 2); // 18
$callback();

COMPOSER

Dependency Manager for PHP

ADDING DEPENDENCIES

IS EASY


  • Copy / Paste
  • Do it yourself
  • Git Submodules

MANAGING THEM CAN BE 

VERY MESSY


ISSUES

  • Your app depends on libraries
  • Keep these libraries up to date
  • Libraries also depend on other libraries

WHAT IS COMPOSER?


  • Resolves inter-package dependencies
  • Installs all dependencies
  • Create an autoloader
  • Follows PSR-0 and PSR-4
  • Inspired by
    • Node.JS NPM
    • Ruby Bundler

HOW TO GET STARTED 

WITH COMPOSER


Install Composer in a local directory:
curl -s https://getcomposer.org/installer | php
Install Composer globally:
curl -s https://getcomposer.org/rinstaller | php
sudo mv composer.phar /usr/local/bin/composer

HOW TO MANAGE 

DEPENDENCIES


  1. Create a sample project and 
  2. Add a composer.json  file
  3. Require specifies packages and version
{
    "require": {
    "php": ">=5.4",
        "guzzlehttp/guzzle": "4.0.*"
    }
} 

INSTALL IT

USE IT


<?php
// test.php
require_once __DIR__.'/vendor/autoload.php';
$client = new GuzzleHttp\Client();

$response = $client->get('https://google.com');
echo $response->getBody();


FIG & PSR

Community driven standards


FRAMEWORK 

INTEROPERABILITY GROUP 


  • Finds commonalities between different Open Source  projects 
  • Develop standards to better work together

PHP STANDARDS 

RECOMMENDATIONS (PSR)

  • These are recommendations
  • PSR-0 The Basic Autoloader
  • PSR-1 Basic Coding Standards
  • PSR-2 Coding Style Guide
  • PSR-3 Logging
  • PSR-4 Autoloader Revised

PSR-0 (AUTOLOADING)

Standard for class naming and autoloading

1. Fully-qualified namespace and class must have the following structure 
\{Vendor Name}\({Namespace}\)*{Class Name} 
2. Each namespace separator is converted to a directory separator when loading from the file system
/VendorName/Namespace/ClassName.php

    WHAT ARE NAMESPACES?


    In practice, it is a language supported way to shorthand long class name and prevent conflicts
    class Foo_Bar_Database_Model {...}
    Instead
    namespace Foo\Bar\Database;
    class Model {...}
    Import/alias the model like this:
    use Foo\Bar\Database\Model;
    use Custom\Database\Model as CustomModel;
    
    class MyController {
        $model = new Model();
        $customModel = new CustomModel();
    }

    PSR-1 (CODING STANDAR)

    Coding conventions to ensure high level of technical interoperability between share PHP code.
    This enables code to run in servers and environments other than the original dev environment. 
      • MUST use  <?php  and <?= tags only
      • MUST use only UTF-8 
      • Files SHOULD either declare symbols or cause side effects
      • Classes and Namespaces MUST follow PSR-0
      • Class names MUST be declared in StudlyCaps
      • Class constants MUST be UC separated by underscores
      • Method names MUST be declared in camelCase

      PSR-2 

      (CODING STYLE GUIDE)

      namespace Vendor\Package;
                                                        // <== Line break
      use OtherVendor\OtherPackage\BazClass;
                                                        // <== Line break      
      class Foo extends Bar implements FooInterface
      {                                                 // <== Brace in new line
          public $var;                                  // <== Visibility 
      
          public function sampleFunction($a, $b = null) // <== Must not have space
          {                                             // <== Brace in new line
              if ($a === $b) {                          // <== Brace in same line
                  bar();                                // <== 4 space indentation
              } else {
                  BazClass::bar($arg2, $arg3);
              }
          }                                             // <== Must be in new line
      }

      PSR-3 (LOGGER) & 

      PSR-4 (AUTOLOADER)

      THE PHP STANDARD 

      LIBRARY

      PHP comes with a set of functionality know as the PHP Standard Library or SPL. Some of this functionality is widely used but some of it isn't.

      DATA STRUCTURES


      These are amongst the least know functionality  in the SPL, yet they can be very helpful.

      Data structures implement the Iterator and Countable interfaces which enable them to be traversed using foreach() and counted using the count().

      Some notable Data Structures are:

      • SplDoublyLinkedList
      • SplHeap
      • SplFixedArray


      SPL DOUBLY LINKED LIST


      • You can move forward or backwards
      • Memory efficient
        • Random reads can be slower that array
      • Can be used as a queue or a stack

      SPL HEAP


      • Complete binary tree that satisfy the heap property
      • Can insert directly into stored position under ideal conditions
      • Is an abstract class
        • Must implement class compare
        • Return 1 if value 1 > value 2
        • Return 0 if value 1 == value 2
        • Return -1 if value 1 < value2
        • You can compare anything, these definitions are up to you

      WORLD CUP EXAMPLE


      class FifaRankingHeap extends \SplHeap {
          protected function compare($value1, $value2) {
              return $value1['points'] - $value2['points'];
      }}
      $heap = new FifaRankingHeap();
      $heap->insert(array('country' => 'Colombia', 'points' => 1137));
      $heap->insert(array('country' => 'Uruguay', 'points' => 1147));
      $heap->insert(array('country' => 'Argentina', 'points' => 1175));
      $heap->insert(array('country' => 'Brazil', 'points' => 1242));
      $heap->insert(array('country' => 'Portugal', 'points' => 1189));
      $heap->insert(array('country' => 'Germany', 'points' => 1300));
      $heap->insert(array('country' => 'Switzerland', 'points' => 1149));
      $i = 2;
      foreach ($heap as $country) {
          echo $i++.$country['country'].' has '.$country['points'].' points.';
      } 
      
      I removed Spain because they are out  :P

      SPL FIXED ARRAY

      Regular arrays are very efficient to read an write, but they can utilize a lot of memory.

      SplFilsedArray is an alternative that performs very well and uses less memory; 

      Unfortunately SplFixedArray can not be used as an associative array and it must have a fixed size.


      EXAMPLE


      class Test {
          public function __destruct(){
              echo "Destroying class ".__CLASS__;
          }
      }
      
      $array = new \SplFixedArray(6);
      $array[5] = new Test();
      $array->setSize(5); // Destroying class Test


      QUESTIONS?



      THE END

      REFERENCES


      
      
      • http://code.tutsplus.com/tutorials/psr-huh--net-29314
      • http://www.slideshare.net/lonelywolf/php-psr-standard-2014-0122?qid=541b412b-0812-4e28-9003-19867b79ec09&v=qf1&b=&from_search=1
      • http://www.slideshare.net/jeremykendall/composer-devops20130716
      • http://www.php-fig.org/
      • http://webmozarts.com/2013/06/19/the-power-of-uniform-resource-location-in-php/
      • http://us3.php.net/manual/en/functions.anonymous.php
      • http://en.wikipedia.org/wiki/Anonymous_function
      • https://speakerdeck.com/cassell/obtaining-closure-with-anonymous-functions
      • http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures
      • Garfield, Larry. Interoperability: The Future of PHP, php[architect] Magazine November 2013, Volume 12 - Issue 11
      • Tankersley, Chris. Composer.json for Fun and Profit, php[architect] Magazine August 2013 Volume 12 - Issue 8
      • Thijssen, Joshua. Mastering the SPL Library. Musketeers.me, LLC. July 2013

      The State of PHP

      By Juan Manuel Torres

      The State of PHP

      • 1,886