Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Beyond PSR-7: The magical middleware tour

703 views

Published on

PSR-7 has made its way to become a PHP standard. The Middleware word –
at the same time – has become one of the most prominent buzzwords of
our ecosystem. Are we facing a bust here? Wasn’t PHP invented for the
web? So, what is this fuss all about, if we’re actually only dealing
with good old HTTP requests/responses?

In this talk Marco and Steve will explain the practical implications
of PSR-7, introducing its semantics and explaining how it is already
shaping the present and future of many modern frameworks and tools.

They’ll do this through practical examples: they’ll dissect an entire
HTTP request/response life cycle, and analyze how it gets handled by
Zend Expressive, one modern (micro)framework which allows us to write
PSR-7 middleware applications for the web. They’ll also take into
account other well known (IE Slim) and emerging implementations(*), so
to be able to make some comparisons, but also to see how a whole set
of different components all speak HTTP the same way.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Beyond PSR-7: The magical middleware tour

  1. 1. PHPDay 2016 - Verona, Italy, May 13th 2016 - @marcoshuttle @maraspin Beyond PSR-7 The magical middleware tour
  2. 2. MARCO
  3. 3. EXPLORER
  4. 4. AVID LEARNER
  5. 5. CHOCOLATE LOVER
  6. 6. STEVE
  7. 7. ENJOYS TRAVELLING
  8. 8. SOFTWARE ARCHITECTURES
  9. 9. IN A FEW YEARS...
  10. 10. Software Engineers
  11. 11. START OF THE JOURNEY...
  12. 12. EVERYBODY ON ITS OWN
  13. 13. 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);
  14. 14. LIBRARIES
  15. 15. Include Hell include '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';
  16. 16. MVC Frameworks
  17. 17. IOC FIRST WAVE
  18. 18. 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!');
  19. 19. REINVENTING THE WHEEL
  20. 20. WITH A LITTLE HELP OF...
  21. 21. Microframeworks
  22. 22. IOC NEW WAVE
  23. 23. ONE ISSUE TO SOLVE...
  24. 24. namespace SymfonyComponentHttpFoundation;  class Request {      public static function createFromGlobals(): Request {          return self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_     } } namespace ZendHttpPhpEnvironment;  class Request extends ZendHttpRequest {      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));      } }
  25. 25. NEED FOR A GOOD HTTP ABSTRACTION
  26. 26. SERVER API $_SERVER $_POST $_GET header() setCookie() echo
  27. 27. CLIENT ADAPTERS
  28. 28. PSR-7
  29. 29. PSR-7 GOALS
  30. 30. INTERFACES
  31. 31. PRACTICAL APPLICATIONS AND USABILITY
  32. 32. NO LIMITS
  33. 33. SERVER AND CLIENT
  34. 34. PSR-7 NON-GOALS
  35. 35. CONFORMATION
  36. 36. IMPOSE DETAILS
  37. 37. A VALUE OBJECT IS FOREVER
  38. 38. Pipes and filters
  39. 39. Pizza Example
  40. 40. DECORATOR
  41. 41. interface Pizza class Margherita implements Pizza  class CheeseDecoratedPizza implements Pizza  {      function __construct(Pizza $pizza)  }  class VegetablesDecoratedPizza implements Pizza  {      function __construct(Pizza $pizza)  }
  42. 42. $myFavouritePizza =      new VegatablesDecoratedPizza(          new CheeseDecoratedPizza(              new Margherita()          )      );
  43. 43. MIDDLEWARE
  44. 44. MIDDLEWARE function (Request request): Response  {      ...      response = next(request);      ...      return response;  }
  45. 45. MIDDLEWARE function (Request): Response
  46. 46. MIDDLEWARE function (Request, Response): Response
  47. 47. MIDDLEWARE function (     Request request,      Response response,      callable next  ): Response
  48. 48. HOT WEEK
  49. 49. MIDDLEWARE IN ACTION
  50. 50. 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);      } }
  51. 51. 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);      } }
  52. 52. 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;      } }
  53. 53. Slim
  54. 54. Slim // src/middleware.php  $app­>add(new AccessLog($logger));  $app­>add(new Geolocate());  $app­>add(new ClientIp());  $app­>add(new BasicAuthentication($users));
  55. 55. Radar & Relay
  56. 56. Radar & Relay // web/index.php  $adr­>middle(new BasicAuthentication($users));  $adr­>middle(new ClientIp());  $adr­>middle(new Geolocate());  $adr­>middle(new AccessLog($logger));
  57. 57. Expressive
  58. 58. 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          ]      ] ];
  59. 59. The magical Expressive tour // config/autoload/middleware­pipeline.global.php  return [     'middleware­pipeline' => [          'always' => [              'middleware' => [                  HelperServerUrlMiddleware::class              ], 'priority' => 10000          ],          'routing' => [              'middleware' => [                  ApplicationFactory::ROUTING_MIDDLEWARE,                  HelperUrlHelperMiddleware::class,                  ApplicationFactory::DISPATCH_MIDDLEWARE              ], 'priority' => 1          ],          'error' => [              'middleware' => [], 'error' => true, 'priority' => ­10000          ]      ] ];
  60. 60. ReactPhp
  61. 61. Expressive/ReactPhp // config/autoload/middleware­pipeline.global.php  return [     'dependencies' => [          'factories' => [              React2Psr7StaticFiles::class => React2Psr7StaticFilesFactory::class,          ]      ],     'middleware_pipeline' => [          'static' => [              'middleware' => React2Psr7StaticFiles::class,              'priority' => 100000, // Execute earliest!          ],          ...      ] ];
  62. 62. USE CASES
  63. 63. Debug bar
  64. 64. 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 (UtilsHelpers::isRedirect($response)) {              $this­>debugBar­>stackData();          } else if (FormatNegotiator::getFormat($request) === 'html') {              $response = $this­>createHtmlResponse($response);          } else if (UtilsHelpers::isAjax($request)) {              $response = $this­>createAjaxResponse($response);          }          return $response;      } }
  65. 65. More Available Middleware Storage-Less Sessions Device Detection Analytics Support Robot-Blocking Request Rate Limiting And More...
  66. 66. Roundup PSR-7: A good HTTP abstraction Abstractions VS Implementations Re-Inventing the Wheel is over Middleware is a Hot Topic Beware of Runtime Dangers
  67. 67. THANK YOU VERY MUCH
  68. 68. Resources by by documentation by documentation by documentation PSR-7 By Example Matthew Weier O'Phinney On HTTP, Middleware, and PSR-7 Matthew Weier O'Phinney Slim framework Slim resources Radar Radar and middleware resources Paul M. Jones Zend Expressive Proposed Middleware Interface PSR-N
  69. 69. Speakers love feedback Leave your feedback at https://joind.in/talk/1ccba Marco Steve @marcoshuttle m.perone@mvlabs.it @maraspin s.maraspin@mvassociati.it
  70. 70. ALL YOU NEED IS MIDDLEWARE
  71. 71. Credits Plane 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 Costan John Loo Keith Allison Fasihjee Mirage Kale Roland Godefroy Joe Mabel Shimer College EDM Playlist Thomas Guest publicdomainpictures.net wesharepics.info Nationaal Archief United Press Intl. ericfleming8 Earle M. Pilgrim Mburnat Shyguy24x7 cvander ninjagrl EWAR ElfQrin StockSnap Scott bauer Colin Amada44 Lali Masriera darwinbell costanzimarco sarangib LEEROY.ca Greenpeace Finland

×