The New PHP – DrupalCamp Sao Paulo 2015



The New PHP – DrupalCamp Sao Paulo 2015

0 2


the-new-php


On Github jmolivas / the-new-php

The New PHP

DrupalCamp Sao Paulo 2015

About me

Jesus Manuel Olivas

Drupal 8 Solutions Engineer

I work for FFW

(and you should too)

My names is ....

I work for FFW (Formely knonw as Blink reaction & Propeople

@erikaheidi http://erikaheidi.com/blog/celebrating-php-twenty-years

This session name is "The New PHP", WAT, wait, but PHP is already 20 years old.

Maybe, the not so New PHP could be a better session title.

The most resent PHP version is 5.6.9 and the next major version will be 7.0.

Because we all know 7 came after 5 right.

PHP 7

https://wiki.php.net/rfc/php7timeline

PHP 7 will be released before the end of 2015.

Probably before Drupal 8.

Symfony 3

http://symfony.com/roadmap?version=3.0#checker

Another major release happening by the end of this year and also probably before Drupal 8 too is Symfony 3.

Drupal 8

https://drupalreleasedate.com/

And according to drupalreleasedate.com Drupal 8 will be release on.

Stop talking about promises and focus on taling about what is already out and we can take advantage of.

Symfony

What is Symfony

Symfony is a group of decoupled components and other standalone PHP libraries.

Then, based on these components, Symfony is also a full-stack web framework.

We can define Symfony as a group of decoupled components and other stand alone libraries.

And then based on these components Symfony is a full-stack web framework.

Does anyone knows which aproach is Drupal 8 using ?

Drupal is not using Symfony as a full stack framework.

Drupal is only taking advantage of some specific components.

Drupal dependencies

core/composer.json

What is the benefit of reusing more code.

The way to be more productive is to write less code and to reuse more code.

Sharing is how Open Source works

The Best Code is No Code At All -- Jeff Atwood Code is bad. It rots. It requires periodic maintenance. It has bugs that need to be found. New features mean old code has to be adapted. -- Rich Skrenta

The more code you have, the more places there are for bugs to hide.

The more code you have, the more code you need to maintain.

Standards Recommendations

Framework Interoperability Group

http://www.php-fig.org

Some people say is like the United Nations of the PHP, but I am not sure if that is a good or bad reference.

The idea behind this group is to group the project representatives of different frameworks to talk about the similitudes between the projects and find ways to work together.

Accepted recommendations

  • PSR-0 Autoloading Standard
  • PSR-1 Coding Standards
  • PSR-2 Coding Style Guide
  • PSR-3 Logger Interface
  • PSR-4 Improved Autoloading
  • PSR-7 HTTP Message Interfaces

Library sharing

Composer

http://getcomposer.org/

Composer is a Dependency Manager for PHP.

It allows you to declare the dependent libraries your project needs and take care of downloading.

Probably this library you are requiring is also dependent on another library or libraries, well worry not composer will resolve that too.

Download Composer

$ curl -sS https://getcomposer.org/installer | php​

$ chmod +x composer.phar

$ mv composer.phar /usr/local/bin/composer

How to use Composer

$ composer init 

$ composer search faker

$ composer show fzaninotto/faker

$ composer require fzaninotto/faker:v1.3.0

How to use Composer

/* composer.json */
{
    "require": {
        "fzaninotto/faker": "v1.3.0"
    }
}

$ composer install

$ composer update

$ composer show --installed

Awesome now you know how to handle, third party dependencies in every moder PHP framework but not Drupal.

Because ...

Composer Manager

$ drush dl composer_manager

$ drush en -y composer_manager

$ drush composer-manager-init

http://drupal.org/project/composer_manager

As a friend of mine Luis Cordova a developer from Perú, but this is drupal/drupal and it won't be that easy.

And I need to say he is maybe right, seems like we use to make thing harder or maybe not hareder, just different "Drupalisims anyone"

We already have drush why not use for this purpose ...

  • No more Copy/Paste of libraries
  • Resolves dependencies
  • Each project defines its own requirements
  • Performs build tasks

Packagist

https://packagist.org/

Where are those libraries definitions stored.

All those libraries are stored at Packagist, the PHP archivist.

Why composer and packagist are important?

Which problem they solved ?

You may be wonder why having an standard mechanisim for sharing libraries is so important.

We already have drush and drush help us to download modules.

The CopyPasta era

Remeber the copy-pasta era, where you just copy/paste code from a geocities page you found atfer searching using yahoo or altavista.

Oh boy ... the good old days.

Then you learn the cool kids those days used to visit phpclasses.org to download libraries.

Fortunely those days are over.

Why release my code as a package or library?

You sould try to move the generic and reusable logic to and external repository and share at github/bitbucket or other.

Same Library can be shared accross differents projects, CMS and frameworks. (Drupal 7/8, Symfony, Silex, Laravel, Wordpress, Backdrop, etc.)

And create repo availabe at github/bitbucket or other. Your module, bundle, plugin, service provider etc... must be only a wrapper for the external library.

Drupal Commerce

https://github.com/commerceguys/commerce

The HTTP Lifecycle

In every web application, in any language, you always have one goal, read and understand the incoming HTTP request in order to create and return the appropriate HTTP response.

In every web application regardless of the used language or framework.

You are probably working with PHP using Symfony, Silex, Drupal or Laravel or may you are working with Pyhton using Django or Flask, how about Ruby using Rails or Java developing with Scala.

Your only goal as a web developer is to properly understand the incoming HTTP Request in order to build and return and appropiate HTTP response.

The client sends an HTTP request. When I said client this could be a web-site, mobile app or even an application runing from the terminal.

Now as I mentioned before it is your responsability to build a proper response, this will be based on what the client is asking for, this could be anything form a HTML page to JSON, XML even and attachment or a multimedia file as well.

The Request/Response Flow

Well the flow looks like this.

Symfony/Silex/Drupal use the front controller design-pattern. This mean every single request is routed from a PHP file app.php or app_ENV.php in the case of Symfony and index.php if using Silex or Drupal. The main goal of the front controller is to bootstrap your Application and performing the global initialization of required objects.

Also takes care of extracting information form the requested URL about the path and match this on the routing system and then execute the proper Controller.

Routing

A route is a map from a URL path to a controller.

We can define a Route as a map from a URL to a controller.

Is in the route definition where where we especify the path for a resource and the controller that will be executed.

Now that I have been mentioning the Controller

Controller

A controller is a PHP method or call-back that takes information from the HTTP request and constructs and returns an HTTP response.

A Controller is a method or call-back that takes information from the HTTP request object and based on the implemented code contructs and returns a proper HTTP response.

Lets see how these two looks in code.

Route/Controller - Symfony

src/AppBundle/resources/config/routing.yml

hello_name:
    path:     /hello/{name}
    defaults: { _controller: AppBundle:Hello:index }

src/AppBundle/Controller/HelloController.php

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Response;

class HelloController {

  public function indexAction($name) {
    return new Response('Hello '.$name);
  }
}

In order to add a new route and the matching controller in Symfony we need to declare this on the Bundle routing.yml file.

Within this file, the Route name, the matching Path and the executed controller must be given.

A Controller class must be added this class must containing a method that returns the proper HTTP response.

Remeber what I told you about Symfony-isms. If you pay attention to the _controller: key value it does not include the words Controller for the Class and Action for the method, what it means for this case we are using a shortcut not the fully qualified path name.

Route/Controller - Silex

web/index.php

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->get('/hello/{name}', function($name) {
    return 'Hello '.$name;
});

$app->run();

Silex it is a Microframework and by default is more simple, what you see here is a complete Silex aplication.

The way I am registering a new route in this code is:

Creating a new instance of the Silex/Application class and using the get method on the app object. You may also use post/match methods depending on your needs.

The get() method it's exepecting two arguments the first is the path of the resource and the second is a closure or anonymous function, from there we can return a String

What if my application need to scale and grow.

Route/Controller - Silex

web/index.php

$app->get(
  '/hello-controller/{name}',
  'DrupalCampSP\Controller\HelloController::indexAction'
);

src/DrupalCampSP/Controller/HelloController.php

namespace DrupalCampSP\Controller;

use Symfony\Component\HttpFoundation\Response;

class HelloController {
  public function indexAction($name) {
    return new Response('Hello '.$name);
  }
}

One common misconception about Silex and microframeworks in general is that they are only for small, simple app and APIs. Which is not true

When you need to scale your Silex app, you need to organize and structure your code into different file classes.

For this example a new Controller class must be created with a method returning a HTTP Response object. Yeah the exact same code we use on the Symfony example. Do you see where I am going.

In order to register this ControllerClass we replaced the second argument passed to the get() method and use the fully qualified path name and the methodName separated by double ::

As you can see here, we are using Controller and Action.

Route/Controller - Drupal

drupalcampsp.routing.yml

drupalcampsp.hello_controller:
  path: 'hello/{name}'
  defaults:
    _content: '\Drupal\drupalcampsp\Controller\HelloController::index'

src/Controller/HelloController.php

namespace Drupal\drupalcampsp\Controller;

class HelloController {

  public function index($name)
  {
    return [
        '#type' => 'markup',
        '#markup' => $this->t('Hello @name!', ['@name' => $name])
    ];
  }
}

In order to achieve this in Drupal we declares a new route at the MODULE_NAME.routing.yml file, adding the Route name and Path.

But instead of using _controller we will replace it with _content 'That was a Drupal-isms' and point to the Controller the same way we did it on Silex, we will be using the fully qualified path name plus :: methodName.

A new Controller Class must be added with a method that could return a String.

As you can see it's kinda a mix of Symfony & Silex but the final result is pretty similar and we shared a lot of concepts and code.

3rd party libraries and projects

You should be using

Seriously

Testing

PHPUnit is a programmer-oriented testing framework for PHP.

https://phpunit.de/

Behat is an open source behavior-driven development framework for PHP 5.3 and 5.4.

http://behat.org

PHP Coding Standards Fixer

http://cs.sensiolabs.org/

Insight

https://insight.sensiolabs.com/

Security Vulnerability Checker

https://security.sensiolabs.org/

WebProfiler

Collects information about each request made to your application and allows you to visualize it in the browser.

WebProfiler

Symfony

Silex

Drupal

LadyBug

Ladybug provides an easy and extensible var_dump/print_r replacement for PHP 5.3+.

https://github.com/raulfraile/ladybug

LadyBug

Symfony

https://github.com/raulfraile/LadybugBundle

Silex

https://github.com/bangpound/ladybug-silex-provider

Drupal

https://www.drupal.org/project/ld

Console

The Console component allows you to create command-line commands.

Console

Symfony

https://github.com/symfony/Console

Silex

https://github.com/KnpLabs/ConsoleServiceProvider

Drupal

http://drupalconsole.com/

DrupalCI

This project is intended as a collection and organization point for the "Modernizing Testbot" project

https://www.drupal.org/project/drupalci

Terra is the spiritual successor to Aegir & DevShop. Terra uses Docker and Docker compose to stand up websites.

https://github.com/terra-ops/terra-app

Drocker.io - A framework designed for Drupal to build fast, isolated development environments using Docker.

http://drocker.io/

Questions & Feedback

Feel free to stalk me during the event or ask any question at:

@jmolivas

http://bit.ly/dcsp2015-new-php

The New PHP DrupalCamp Sao Paulo 2015