beyond psr-7: the magical middleware tour

80
PHPDay 2016 - Verona, Italy, May 13 th 2016 - @marcoshuttle @maraspin Beyond PSR-7 The magical middleware tour

Upload: marco-perone

Post on 10-Jan-2017

312 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Beyond PSR-7: The magical middleware tour

PHPDay 2016 - Verona, Italy, May 13th 2016 - @marcoshuttle @maraspin

Beyond PSR-7The magical middleware tour

Page 2: Beyond PSR-7: The magical middleware tour

MARCO

Page 3: Beyond PSR-7: The magical middleware tour

EXPLORER

Page 4: Beyond PSR-7: The magical middleware tour

AVID LEARNER

Page 5: Beyond PSR-7: The magical middleware tour

CHOCOLATE LOVER

Page 6: Beyond PSR-7: The magical middleware tour

STEVE

Page 7: Beyond PSR-7: The magical middleware tour

ENJOYS TRAVELLING

Page 8: Beyond PSR-7: The magical middleware tour

SOFTWARE ARCHITECTURES

Page 9: Beyond PSR-7: The magical middleware tour

IN A FEW YEARS...

Page 10: Beyond PSR-7: The magical middleware tour

Software Engineers

Page 11: Beyond PSR-7: The magical middleware tour

START OF THE JOURNEY...

Page 12: Beyond PSR-7: The magical middleware tour

EVERYBODY ON ITS OWN

Page 13: Beyond PSR-7: The magical middleware tour

A Total Mess$filename = 'log.txt'; $handle = fopen($filename, 'a')); fwrite($handle, $errorMessage); fclose($handle);

$filename = 'log.txt'; $handle = fopen($filename, 'a')); fwrite($handle, $errorMessage); fclose($handle);

Page 14: Beyond PSR-7: The magical middleware tour

LIBRARIES

Page 15: Beyond PSR-7: The magical middleware tour

Include Hellinclude 'config.php'; include_once 'dbcon.php'; include_once 'logger.php'; include 'utils.php'; include 'forms.php'; include 'calculations.php'; include 'graphs.php'; include 'auth.php';

Page 16: Beyond PSR-7: The magical middleware tour

MVC Frameworks

Page 17: Beyond PSR-7: The magical middleware tour

IOC FIRST WAVE

Page 18: Beyond PSR-7: The magical middleware tour

Same things, different ways...Zend Framework

Symfony

$logger = new Zend_Log(); $writer = new Zend_Log_Writer_Stream('php://output'); $logger­>addWriter($writer); $logger­>log('Hello PHPDay People!', Zend_Log::INFO);

// YAML Configuration // [...] sfContext::getInstance()­>getLogger()­>info('Hello PHPDay People!');

Page 19: Beyond PSR-7: The magical middleware tour

REINVENTING THE WHEEL

Page 20: Beyond PSR-7: The magical middleware tour

WITH A LITTLE HELP OF...

Page 21: Beyond PSR-7: The magical middleware tour
Page 22: Beyond PSR-7: The magical middleware tour

Microframeworks

Page 23: Beyond PSR-7: The magical middleware tour

IOC NEW WAVE

Page 24: Beyond PSR-7: The magical middleware tour

ONE ISSUE TO SOLVE...

Page 25: Beyond PSR-7: The magical middleware tour

namespace Symfony\Component\HttpFoundation;

class Request public static function createFromGlobals(): Request return self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);

namespace Zend\Http\PhpEnvironment;

class Request extends \Zend\Http\Request public function __construct() $this­>setEnv(new Parameters($_ENV)); $this­>setQuery(new Parameters($_GET)); $this­>setPost(new Parameters($_POST)); $this­>setCookies(new Parameters($_COOKIE)); $this­>setFiles(new Parameters($this­>mapPhpFiles())); $this­>setServer(new Parameters($_SERVER));

Page 26: Beyond PSR-7: The magical middleware tour

NEED FOR

A GOOD HTTP ABSTRACTION

Page 27: Beyond PSR-7: The magical middleware tour

SERVER API

$_SERVER

$_POST

$_GET

header()

setCookie()

echo

Page 28: Beyond PSR-7: The magical middleware tour

CLIENT ADAPTERS

Page 29: Beyond PSR-7: The magical middleware tour

PSR-7

Page 30: Beyond PSR-7: The magical middleware tour

PSR-7 GOALS

Page 31: Beyond PSR-7: The magical middleware tour

INTERFACES

Page 32: Beyond PSR-7: The magical middleware tour

PRACTICAL APPLICATIONS AND USABILITY

Page 33: Beyond PSR-7: The magical middleware tour

NO LIMITS

Page 34: Beyond PSR-7: The magical middleware tour

SERVER AND CLIENT

Page 35: Beyond PSR-7: The magical middleware tour

PSR-7 NON-GOALS

Page 36: Beyond PSR-7: The magical middleware tour

CONFORMATION

Page 37: Beyond PSR-7: The magical middleware tour

IMPOSE DETAILS

Page 38: Beyond PSR-7: The magical middleware tour
Page 39: Beyond PSR-7: The magical middleware tour

A VALUE OBJECT IS FOREVER

Page 40: Beyond PSR-7: The magical middleware tour
Page 41: Beyond PSR-7: The magical middleware tour

Pipes and filters

Page 42: Beyond PSR-7: The magical middleware tour

Pizza Example

Page 43: Beyond PSR-7: The magical middleware tour

DECORATOR

Page 44: Beyond PSR-7: The magical middleware tour

interface Pizza

class Margherita implements Pizza

class CheeseDecoratedPizza implements Pizza function __construct(Pizza $pizza)

class VegetablesDecoratedPizza implements Pizza function __construct(Pizza $pizza)

Page 45: Beyond PSR-7: The magical middleware tour

$myFavouritePizza =

new VegatablesDecoratedPizza(

new CheeseDecoratedPizza(

new Margherita()

)

);

Page 46: Beyond PSR-7: The magical middleware tour

MIDDLEWARE

Page 47: Beyond PSR-7: The magical middleware tour
Page 48: Beyond PSR-7: The magical middleware tour
Page 49: Beyond PSR-7: The magical middleware tour
Page 50: Beyond PSR-7: The magical middleware tour
Page 51: Beyond PSR-7: The magical middleware tour

MIDDLEWAREfunction (Request request): Response ...

response = next(request);

...

return response;

Page 52: Beyond PSR-7: The magical middleware tour

MIDDLEWAREfunction (Request): Response

Page 53: Beyond PSR-7: The magical middleware tour

MIDDLEWAREfunction (Request, Response): Response

Page 54: Beyond PSR-7: The magical middleware tour

MIDDLEWAREfunction (

Request request,

Response response,

callable next

): Response

Page 55: Beyond PSR-7: The magical middleware tour

HOT WEEK

Page 56: Beyond PSR-7: The magical middleware tour

MIDDLEWARE IN ACTION

Page 57: Beyond PSR-7: The magical middleware tour

class Middleware function __invoke($request, $response, $next) if (!$this­>preconditionsExist($request, $response)) throw new RuntimeException();

$request = $this­>doSomethingOnRequest($request);

$response = $next($request, $response);

return $this­>doSomethingOnResponse($response);

Page 58: Beyond PSR-7: The magical middleware tour

class BasicAuthentication function __invoke($request, $response, $next) $authorization = $request­>getHeaderLine('Authorization');

if ($this­>checkUserPassword($authorization)) $request = self::setAttribute( $request, 'USERNAME', $authorization['username'] );

return $next($request, $response);

return $this­>unauthorizedUserResponse($response);

Page 59: Beyond PSR-7: The magical middleware tour

class AccessLog function __invoke($request, $response, $next) if (!self::hasAttribute($request, 'CLIENT_IPS')) throw new RuntimeException();

$response = $next($request, $response);

$message = $this­>createMessage($request, $response);

$this­>logger­>log($message);

return $response;

Page 60: Beyond PSR-7: The magical middleware tour

Slim

Page 61: Beyond PSR-7: The magical middleware tour

Slim

// src/middleware.php

$app­>add(new AccessLog($logger));

$app­>add(new Geolocate());

$app­>add(new ClientIp());

$app­>add(new BasicAuthentication($users));

Page 62: Beyond PSR-7: The magical middleware tour

Radar & Relay

Page 63: Beyond PSR-7: The magical middleware tour

Radar & Relay

// web/index.php

$adr­>middle(new BasicAuthentication($users));

$adr­>middle(new ClientIp());

$adr­>middle(new Geolocate());

$adr­>middle(new AccessLog($logger));

Page 64: Beyond PSR-7: The magical middleware tour

Expressive

Page 65: Beyond PSR-7: The magical middleware tour

Expressive

// config/autoload/middleware­pipeline.global.php return [ 'middleware­pipeline' => [ 'basic_authentication' => [ 'middleware' => new BasicAuthentication($users), 'priority' => 4000 ], 'clientip' => [ 'middleware' => ClientIp::class, 'priority' => 3000 ], 'geolocate' => [ 'middleware' => Geolocate::class, 'priority' => 2000 ], 'access­log' => [ 'middleware' => new AccessLog($logger), 'priority' => 1000 ] ]];

Page 66: Beyond PSR-7: The magical middleware tour

The magical Expressive tour

// config/autoload/middleware­pipeline.global.php return [ 'middleware­pipeline' => [ 'always' => [ 'middleware' => [ Helper\ServerUrlMiddleware::class ], 'priority' => 10000 ], 'routing' => [ 'middleware' => [ ApplicationFactory::ROUTING_MIDDLEWARE, Helper\UrlHelperMiddleware::class, ApplicationFactory::DISPATCH_MIDDLEWARE ], 'priority' => 1 ], 'error' => [ 'middleware' => [], 'error' => true, 'priority' => ­10000 ] ]];

Page 67: Beyond PSR-7: The magical middleware tour

ReactPhp

Page 68: Beyond PSR-7: The magical middleware tour

Expressive/ReactPhp

// config/autoload/middleware­pipeline.global.php return [ 'dependencies' => [ 'factories' => [ React2Psr7\StaticFiles::class => React2Psr7\StaticFilesFactory::class, ] ], 'middleware_pipeline' => [ 'static' => [ 'middleware' => React2Psr7\StaticFiles::class, 'priority' => 100000, // Execute earliest! ], ... ]];

Page 69: Beyond PSR-7: The magical middleware tour
Page 70: Beyond PSR-7: The magical middleware tour

USE CASES

Page 71: Beyond PSR-7: The magical middleware tour

Debug bar

Page 72: Beyond PSR-7: The magical middleware tour

class DebugBar public function __invoke($request, $response, $next) if (!self::hasAttribute($request, FormatNegotiator::KEY)) throw new RuntimeException('Need FormatNegotiator executed before');

if ($this­>isAsset($request)) return $this­>responsewithAssetBody($request, $response); $response = $next($request, $response);

if (Utils\Helpers::isRedirect($response)) $this­>debugBar­>stackData(); else if (FormatNegotiator::getFormat($request) === 'html') $response = $this­>createHtmlResponse($response); else if (Utils\Helpers::isAjax($request)) $response = $this­>createAjaxResponse($response); return $response;

Page 73: Beyond PSR-7: The magical middleware tour

More Available Middleware

Storage-Less Sessions

Device Detection

Analytics Support

Robot-Blocking

Request Rate Limiting

And More...

Page 74: Beyond PSR-7: The magical middleware tour

RoundupPSR-7: A good HTTP abstraction

Abstractions VS Implementations

Re-Inventing the Wheel is over

Middleware is a Hot Topic

Beware of Runtime Dangers

Page 75: Beyond PSR-7: The magical middleware tour

THANK YOU VERY MUCH

Page 78: Beyond PSR-7: The magical middleware tour

Speakers love feedback

Leave your feedback at https://joind.in/talk/1ccba

Marco

Steve

@marcoshuttle [email protected]

@maraspin [email protected]

Page 79: Beyond PSR-7: The magical middleware tour

ALL YOU NEED IS MIDDLEWARE

Page 80: Beyond PSR-7: The magical middleware tour

CreditsPlane view by Chocolate by Orioles Fan by Mosque by Fans by Hippies by Hippie Van by Students by Rave by Weird Bicicle by Suitcase found at A320 model found at Beatles picture by Beatles picture by Board by Abstract painting by

Figs by Kungsleden by Danger zone by PSR-7 diagram by Diamond by Pizza by Cheese and vegetables by Pizza by Onion by Onion by Cutting onion by Onion by Onion by Onion by Locked door by Log by

Victor CostanJohn LooKeith Allison

FasihjeeMirage Kale

Roland GodefroyJoe Mabel

Shimer CollegeEDM Playlist

Thomas Guestpublicdomainpictures.net

wesharepics.infoNationaal ArchiefUnited Press Intl.

ericfleming8Earle M. Pilgrim

MburnatShyguy24x7cvander

ninjagrlEWAR

ElfQrinStockSnap

Scott bauerColinAmada44

Lali Masrieradarwinbellcostanzimarcosarangib

LEEROY.caGreenpeace Finland