Silex and Twig (PHP Dorset talk)

87

description

Alex Ross and I gave an introduction to the Silex web framework and the Twig templating language. Given at PHP Dorset.

Transcript of Silex and Twig (PHP Dorset talk)

Page 1: Silex and Twig (PHP Dorset talk)
Page 2: Silex and Twig (PHP Dorset talk)

Silex and TwigJon Ginn

Page 3: Silex and Twig (PHP Dorset talk)

Silex and TwigJon Ginn

Page 4: Silex and Twig (PHP Dorset talk)
Page 5: Silex and Twig (PHP Dorset talk)
Page 6: Silex and Twig (PHP Dorset talk)

Silex and TwigAlex Ross and Dave Hulbert

Page 7: Silex and Twig (PHP Dorset talk)
Page 8: Silex and Twig (PHP Dorset talk)
Page 9: Silex and Twig (PHP Dorset talk)

Alex@rosseySenior engineer at Base*

*we’re hiring

Dave@dave1010Tech lead at Base*

wearebase.com

Page 10: Silex and Twig (PHP Dorset talk)

Alex@rosseySenior engineer at Base*

*we’re hiring

Dave@dave1010Tech lead at Base*

wearebase.com

Page 11: Silex and Twig (PHP Dorset talk)

Silex and Twig

Page 12: Silex and Twig (PHP Dorset talk)

Silex

Page 13: Silex and Twig (PHP Dorset talk)
Page 14: Silex and Twig (PHP Dorset talk)

Micro-framework?a what?

Page 15: Silex and Twig (PHP Dorset talk)

Framework?...?

Page 16: Silex and Twig (PHP Dorset talk)

“A structure for applications”

(and usually a library of tools too)

Page 17: Silex and Twig (PHP Dorset talk)
Page 18: Silex and Twig (PHP Dorset talk)

Silex

● a simple web application structure that doesn’t get in your way

● library of tools = Symfony Components

Page 19: Silex and Twig (PHP Dorset talk)

Code!

Page 20: Silex and Twig (PHP Dorset talk)

// use the Request$name = $_GET['name'];

// do some fun stuff$name = strtoupper($name);

// send back a Responseecho 'Hello ' . htmlspecialchars($name);

Page 21: Silex and Twig (PHP Dorset talk)
Page 22: Silex and Twig (PHP Dorset talk)
Page 23: Silex and Twig (PHP Dorset talk)

tightly coupling :-(

Tying your code to the input and output:● Input, global states (Request)

○ $_SERVER, $_GET, $_POST, $_REQUEST, $_FILES, $_COOKIE, $_ENV

● Output (Response)○ echo*, print, printf, die, exit

*we could test this with ob_start, ob_get_clean

Page 24: Silex and Twig (PHP Dorset talk)
Page 25: Silex and Twig (PHP Dorset talk)

What if we wanted to make it

● a JSON API?● send the response as an email or SMS?● a commandline program?● an enterprise SOAP Service?● communicate via Morse code / Enigma

machine?

Page 26: Silex and Twig (PHP Dorset talk)
Page 27: Silex and Twig (PHP Dorset talk)

Dirty code (STUPID)

● S - Singletons and Globals● T - Tight Coupling● U - Untestable code● P - Premature Optimisation● I - In-descriptive Naming● D - Duplication● D - Duplication

Page 28: Silex and Twig (PHP Dorset talk)
Page 29: Silex and Twig (PHP Dorset talk)

Testability(PHPUnit)

Page 30: Silex and Twig (PHP Dorset talk)

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

$app = new Silex\Application();

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

$app->run();

Page 31: Silex and Twig (PHP Dorset talk)

#!/usr/bin/env rubyrequire 'sinatra'

get '/hello/:name' do "Hello #{params[:name]}!"end

Page 32: Silex and Twig (PHP Dorset talk)

var express = require('express');var app = express();

app.get('/hello.txt', function(req, res) { res.send('hello world'); });

Page 33: Silex and Twig (PHP Dorset talk)
Page 34: Silex and Twig (PHP Dorset talk)

Clean code

● Modular● Reusable● Easy to extend or change● Easy to read and understand● Easy to refactor (maintainable)● Easy to test

Page 35: Silex and Twig (PHP Dorset talk)
Page 36: Silex and Twig (PHP Dorset talk)

SOLID

● S - SRP● O - OCP● L - LSP● I - ISP● D - DIP

Page 37: Silex and Twig (PHP Dorset talk)

SOLID

● S - Single Responsibility Principle● O - Open / Closed Principle● L - Liskov Substitution Principle● I - Interface Segregation Principle● D - Dependency Inversion Principle

Page 38: Silex and Twig (PHP Dorset talk)

3

Page 39: Silex and Twig (PHP Dorset talk)

3-ish

Page 40: Silex and Twig (PHP Dorset talk)

1.2

Page 41: Silex and Twig (PHP Dorset talk)

10

Page 42: Silex and Twig (PHP Dorset talk)

3

Page 43: Silex and Twig (PHP Dorset talk)

Single Responsibility Principle

One reason to change

Page 44: Silex and Twig (PHP Dorset talk)
Page 45: Silex and Twig (PHP Dorset talk)

Open / Closed PrincipleOpen for extension

Closed for modification

Page 46: Silex and Twig (PHP Dorset talk)
Page 47: Silex and Twig (PHP Dorset talk)

Liskov Substitution Principle

Extending a class shouldn’t break stuff

Page 48: Silex and Twig (PHP Dorset talk)
Page 49: Silex and Twig (PHP Dorset talk)
Page 50: Silex and Twig (PHP Dorset talk)

Interface Segregation Principle

Don’t depend on stuff you don’t use

Page 51: Silex and Twig (PHP Dorset talk)
Page 52: Silex and Twig (PHP Dorset talk)

Dependency Inversion Principle

Depend on a concept (abstractions),not an implementation

Page 53: Silex and Twig (PHP Dorset talk)
Page 54: Silex and Twig (PHP Dorset talk)

application business logic

Response object

wraps $_SERVER, $_REQUEST, etc nicely headers and body

Request object

GET RETURN

Separation of concerns :-)

Page 55: Silex and Twig (PHP Dorset talk)

A test(PHPUnit)

Page 56: Silex and Twig (PHP Dorset talk)

use Silex\WebTestCase;

class ContactFormTest extends WebTestCase{ public function testTheContactPage() { $client = $this->createClient(); $crawler = $client->request('GET', '/contact');

$this->assertTrue($client->getResponse()->isOk()); $this->assertCount(1, $crawler->filter('h1:contains("Contact us")')); $this->assertCount(1, $crawler->filter('form')); $this->assertCount(1, $crawler->filter('input:contains("Say hi!")')); }}

Page 57: Silex and Twig (PHP Dorset talk)

Make the test pass

Page 58: Silex and Twig (PHP Dorset talk)
Page 59: Silex and Twig (PHP Dorset talk)
Page 60: Silex and Twig (PHP Dorset talk)

HttpKernelInterfaceCreates flexible and fast HTTP-based

applications

Page 61: Silex and Twig (PHP Dorset talk)

interface HttpKernelInterface

{ const MASTER_REQUEST = 1;

const SUB_REQUEST = 2;

public function handle( Request $name, $type = self::MASTER_REQUEST, $catch = true ) {}

}

Page 62: Silex and Twig (PHP Dorset talk)

/**

* Handles a Request to convert it to a Response.

*

* When $catch is true, the implementation must catch all exceptions

* and do its best to convert them to a Response instance.

*

* @param Request $request A Request instance

* @param integer $type The type of the request (MASTER_REQUEST or SUB_REQUEST)

* @param Boolean $catch Whether to catch exceptions or not

* @return Response A Response instance

* @throws \Exception When an Exception occurs during processing

*/

Page 63: Silex and Twig (PHP Dorset talk)

/**

* Handles a Request to convert it to a Response.

*

* When $catch is true, the implementation must catch all exceptions

* and do its best to convert them to a Response instance.

*

* @param Request $request A Request instance

* @param integer $type The type of the request (MASTER_REQUEST or SUB_REQUEST)

* @param Boolean $catch Whether to catch exceptions or not

* @return Response A Response instance

* @throws \Exception When an Exception occurs during processing

*/

Page 64: Silex and Twig (PHP Dorset talk)

http://stackphp.com

Page 65: Silex and Twig (PHP Dorset talk)

Used by

● Symfony● Laravel● Drupal● phpBB

Page 66: Silex and Twig (PHP Dorset talk)

A Silex App *is* Pimple

● Simple container with ~80 lines of code● ArrayAccess interface● *IoC container, for dependency injection● Allows you to loosely couple your classes

*IoC = Inversion of Control

Page 67: Silex and Twig (PHP Dorset talk)
Page 68: Silex and Twig (PHP Dorset talk)
Page 69: Silex and Twig (PHP Dorset talk)

Twig

Page 70: Silex and Twig (PHP Dorset talk)

Better than mixingPHP & HTML

Page 71: Silex and Twig (PHP Dorset talk)
Page 72: Silex and Twig (PHP Dorset talk)

Separation

Page 73: Silex and Twig (PHP Dorset talk)

Variables{{ title }}

{{ var|escape }}

{{ foo.bar }}

Page 74: Silex and Twig (PHP Dorset talk)

Control blocks

{% for user in users %} * {{ user.name }}{% else %} No users have been found.{% endfor %}

Page 75: Silex and Twig (PHP Dorset talk)

Filters

{{ name|striptags|title|reverse }}

Page 76: Silex and Twig (PHP Dorset talk)

Includes

{% include 'sidebar.html' %}

Page 77: Silex and Twig (PHP Dorset talk)

Inheritancebase.twig<title>{% block title %}My site{% endblock %}</title><div>{% block content %}{% endblock %}</div>

child.twig{% extends "base.twig" %}{% block title %}Contact us{% endblock %}{% block content %}Email{% endblock %}

Page 78: Silex and Twig (PHP Dorset talk)

Twig in the wild

Page 79: Silex and Twig (PHP Dorset talk)
Page 80: Silex and Twig (PHP Dorset talk)
Page 81: Silex and Twig (PHP Dorset talk)
Page 82: Silex and Twig (PHP Dorset talk)

Silex & Twig

Silex comes with a bridge that provides a Twig service

Register the service and you get twig

Page 83: Silex and Twig (PHP Dorset talk)

"require": { "twig/twig": ">=1.8,<2.0-dev"}

$app->register(new Silex\Provider\TwigServiceProvider(), array( 'twig.path' => __DIR__ . '/views',));

$app->get('/hello/{name}', function ($name) use ($app) { return $app['twig']->render('hello.twig', array( 'name' => $name, ));});

Page 84: Silex and Twig (PHP Dorset talk)

Silex in the wildWordPress Example

Page 85: Silex and Twig (PHP Dorset talk)
Page 86: Silex and Twig (PHP Dorset talk)

PHP Dorset site

● silex● twig

Page 87: Silex and Twig (PHP Dorset talk)

Any Questions & Thank You

Feedback: goo.gl/TnkeCTSildes: goo.gl/ilu1rl

Alex (@rossey) & Dave (@dave1010)wearebase.com/hiring

Tweet Jon Ginn (@jonginn) and tell him what he missed!