Pro Yearly is on sale from $80 to $50! »

Modern HTTP handling with PHP - Confoo Montreal 2018

Modern HTTP handling with PHP - Confoo Montreal 2018

PSR-7 describes common interfaces for representing HTTP messages. HTTP messages are the foundation of web development. Web browsers and HTTP clients such as cURL create HTTP request messages that are sent to a web server, which provides an HTTP response message. Server-side code receives an HTTP request message, and returns an HTTP response message.

39eb3f3d313b13f05534e496285040b8?s=128

Hannes Van De Vreken

March 09, 2018
Tweet

Transcript

  1. HTTP messages Modern way of dealing with HTTP in PHP

    @hannesvdvreken #confoo
  2. Hi, my name is Hannes.

  3. !

  4. None
  5. None
  6. PSR-7 Common interfaces for HTTP messages

  7. 1. psr/http-message 2. Server side 3. Client side

  8. 1. psr/http-message

  9. HTTP application PSR/HTTP-MESSAGE

  10. PHP Script: $_SERVER - $_GET - $_POST - $_COOKIES -

    $_FILES PSR/HTTP-MESSAGE
  11. Frameworks Zend, Symfony, Laravel, Silex, CakePHP, … PSR/HTTP-MESSAGE

  12. composer require symfony/http-foundation composer require zendframework/zend-http PSR/HTTP-MESSAGE (RFC 7230 -

    7231)
  13. Example: Middleware that checks Authorization header from Request PSR/HTTP-MESSAGE

  14. Example: Image library that generates a Response object for an

    image path PSR/HTTP-MESSAGE
  15. Example: $response->send(); PSR/HTTP-MESSAGE

  16. Example: symfony/http-foundation: RequestStack::class ExpressionRequestMatcher::class PSR/HTTP-MESSAGE

  17. PSR/HTTP-MESSAGE PHP-FIG

  18. Common interfaces for HTTP messages (RFC 7230 - 7231) PSR/HTTP-MESSAGE

  19. Common interfaces for HTTP messages - Works in any Framework

    - Both for HTTP Clients and HTTP applications - HTTP version independent PSR/HTTP-MESSAGE
  20. Common interfaces for HTTP messages RequestInterface ResponseInterface PSR/HTTP-MESSAGE

  21. PSR/HTTP-MESSAGE May 2015: PSR-7 psr/http-message

  22. Differences with Symfony HTTP foundation: Interfaced PSR/HTTP-MESSAGE

  23. Differences with Symfony HTTP foundation: Interfaced Immutable PSR/HTTP-MESSAGE

  24. $newRequest = $request ->withoutHeader($xHeader) ->withHeader(‘referer’, $referer); var_dump($newRequest === $request); >

    false PSR/HTTP-MESSAGE
  25. PSR/HTTP-MESSAGE let’s take a look

  26. PSR/HTTP-MESSAGE GET /try-the-api HTTP/1.1 Host: getstream.io HTTP/1.1 200 OK Date:

    Fri, 09 Mar 2018 14:4
  27. PSR/HTTP-MESSAGE GET /try-the-api HTTP/1.1 Host: getstream.io HTTP/1.1 200 OK Date:

    Fri, 09 Mar 2018 14:4 <doctype html>
  28. PSR/HTTP-MESSAGE GET /try-the-api HTTP/1.1 Host: getstream.io HTTP/1.1 200 OK Date:

    Fri, 09 Mar 2018 14:4 <doctype html>
  29. PSR/HTTP-MESSAGE GET /try-the-api HTTP/1.1 Host: getstream.io HTTP/1.1 200 OK Date:

    Fri, 09 Mar 2018 14:4 <doctype html>
  30. PSR/HTTP-MESSAGE interface RequestInterface { function getProtocolVersion(); function getHeaders(); function getHeader($name);

    function getHeaderLine($name); function getBody(); … } interface ResponseInterface { function getProtocolVersion(); function getHeaders(); function getHeader($name); function getHeaderLine($name); function getBody(); … }
  31. PSR/HTTP-MESSAGE interface RequestInterface implements MessageInterface { function getRequestTarget(); function getUri();

    function getMethod(); } interface ResponseInterface implements MessageInterface { function getStatusCode(); function getReasonPhrase(); }
  32. PSR/HTTP-MESSAGE $newRequest = $request ->withHeader($name, $value); var_dump($newRequest === $request); >

    false
  33. PSR/HTTP-MESSAGE - RECAP MessageInterface RequestInterface ResponseInterface UriInterface ServerRequestInterface ($_GET, $_POST,

    $_SERVER, $_COOKIES, $ StreamInterface
  34. PSR/HTTP-MESSAGE guzzlehttp/psr7 zendframework/zend-diactoros slim/slim

  35. 2. Server side

  36. None
  37. START USING PSR-7 IN YOUR APP What about existing Symfony/Zend

    Request & Response objects?
  38. START USING PSR-7 IN YOUR APP symfony/psr-http-message-bridge zendframework/zend-psr7bridge

  39. START USING PSR-7 IN YOUR APP Symfony request/response object ⁷

    ⁷ ⁷ Zend-Diactoros request/response object
  40. START USING PSR-7 IN YOUR APP Symfony request/response object ⁷

    ⁷ ⁷ Zend-Diactoros request/response object \Psr\Http\Message\RequestInterface type hinted
  41. START USING PSR-7 IN YOUR APP Laravel: public function index(ServerRequestInterface

    $request){ return $psrResponse; }
  42. START USING PSR-7 IN YOUR APP SlimPHP v3: routing &

    middleware
  43. Middleware wrapping HTTP applications

  44. None
  45. MIDDLEWARE DEFINITION Session Logging Authentication Robots.txt file HTTP Cache Firewall

    Cors Throttling …
  46. HTTP MIDDLEWARE PSR-15

  47. MIDDLEWARE DEFINITION interface RequestHandlerInterface { public function handle(
 ServerRequestInterface $request


    ): ResponseInterface; }
  48. MIDDLEWARE DEFINITION interface MiddlewareInterface { public function process( ServerRequestInterface $request,

    RequestHandlerInterface $handler ): ResponseInterface; }
  49. MIDDLEWARE DEFINITION function process( ServerRequestInterface $request, RequestHandlerInterface $handler ) {

    // Alter request, if you want $response = $handler->handle($request); // Alter response, if you want return $response; }
  50. MIDDLEWARE DEFINITION Build your stack with: relay/relay mindplay/middleman …

  51. Demo

  52. https://github.com/php-fig/http-server-middleware HTTP MIDDLEWARE - PSR-15

  53. 3. Client side

  54. GUZZLEHTTP/GUZZLE composer req guzzlehttp/guzzle

  55. GUZZLEHTTP/GUZZLE composer.json ^6.3

  56. GUZZLEHTTP/GUZZLE - WHAT’S NEW PSR-7

  57. GUZZLEHTTP/GUZZLE - PSR-7 guzzlehttp/psr7

  58. GUZZLEHTTP/GUZZLE - PSR-7 - COMPOSER.JSON "provide": { "psr/http-message-implementation": "1.0" },

  59. None
  60. None
  61. GUZZLEHTTP/GUZZLE - PSR-7 use GuzzleHttp\Psr7\Request; $psrRequest = new Request( 'GET',

    $uri, $headers, $body );
  62. GUZZLEHTTP/GUZZLE - PSR-7 $client = new GuzzleHttp\Client(); $psrResponse = $client->send($psrRequest);

  63. GUZZLEHTTP/GUZZLE Demo

  64. GUZZLEHTTP/GUZZLE - PROMISES Promises

  65. GUZZLEHTTP/GUZZLE - PSR-7 guzzlehttp/promise

  66. GUZZLEHTTP/GUZZLE - PROMISES use Psr\Http\Message\ResponseInterface as Res; $promise = $client->sendAsync($request);

    $promise->then(function (Res $response) { $response->getBody(); }); $promise->wait();
  67. GUZZLEHTTP/GUZZLE Demo

  68. GUZZLEHTTP/GUZZLE - MIDDLEWARES Callable middlewares

  69. GUZZLEHTTP/GUZZLE - MIDDLEWARES $middleware = function ($handler) { return function

    ($request, $options) use ($handler) { // Alter request, if you want return $handler($request, $options) ->then(function (ResponseInterface $response) { // Alter response, if you want return $response; }); }; }
  70. GUZZLEHTTP/GUZZLE - MIDDLEWARES $middleware = GuzzleHttp\Middleware::log( $psr3Logger, new GuzzleHttp\MessageFormatter() );

  71. GUZZLEHTTP/GUZZLE - MIDDLEWARES $stack = HandlerStack::create(); $stack->push($middleware); $stack->unshift($middleware); $stack->remove($middleware); $client

    = new Client(['handler' => $stack]);
  72. GUZZLEHTTP/GUZZLE - MIDDLEWARES Demo

  73. Decoupling HTTP Clients

  74. None
  75. interface ClientInterface {
 public function sendRequest(
 RequestInterface $request
 ): ResponseInterface;

    }
  76. RECAP 1. Guzzle PSR-7 2. Promises 3. Middleware 4. Client

    abstraction
  77. RECAP 1. psr/http-message 2. Server side 3. Client side

  78. Thank you! @hannesvdvreken #confoo

  79. Time for questions. @hannesvdvreken #confoo

  80. • https://getstream.io • https://github.com/guzzle/guzzle • https://github.com/php-http • http://docs.guzzlephp.org/en/latest/ • https://github.com/php-fig/http-message

    • https://github.com/php-fig/fig-standards/
 blob/master/accepted/PSR-7-http-message.md REFERENCES