$30 off During Our Annual Pro Sale. View Details »

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.

Hannes Van De Vreken

March 09, 2018
Tweet

More Decks by Hannes Van De Vreken

Other Decks in Programming

Transcript

  1. HTTP messages
    Modern way of dealing with HTTP in PHP
    @hannesvdvreken
    #confoo

    View Slide

  2. Hi, my name is Hannes.

    View Slide

  3. !

    View Slide

  4. View Slide

  5. View Slide

  6. PSR-7
    Common interfaces for HTTP messages

    View Slide

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

    View Slide

  8. 1. psr/http-message

    View Slide

  9. HTTP application
    PSR/HTTP-MESSAGE

    View Slide

  10. PHP Script:
    $_SERVER - $_GET - $_POST -
    $_COOKIES - $_FILES
    PSR/HTTP-MESSAGE

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  14. Example:
    Image library that generates a Response
    object for an image path
    PSR/HTTP-MESSAGE

    View Slide

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

    View Slide

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

    View Slide

  17. PSR/HTTP-MESSAGE
    PHP-FIG

    View Slide

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

    View Slide

  19. Common interfaces for HTTP messages
    - Works in any Framework
    - Both for HTTP Clients and HTTP applications
    - HTTP version independent
    PSR/HTTP-MESSAGE

    View Slide

  20. Common interfaces for HTTP messages
    RequestInterface
    ResponseInterface
    PSR/HTTP-MESSAGE

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  24. $newRequest = $request
    ->withoutHeader($xHeader)
    ->withHeader(‘referer’, $referer);
    var_dump($newRequest === $request);
    > false
    PSR/HTTP-MESSAGE

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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();

    }

    View Slide

  31. PSR/HTTP-MESSAGE
    interface RequestInterface
    implements MessageInterface
    {
    function getRequestTarget();
    function getUri();
    function getMethod();
    }
    interface ResponseInterface
    implements MessageInterface
    {
    function getStatusCode();
    function getReasonPhrase();
    }

    View Slide

  32. PSR/HTTP-MESSAGE
    $newRequest = $request
    ->withHeader($name, $value);
    var_dump($newRequest === $request);
    > false

    View Slide

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

    View Slide

  34. PSR/HTTP-MESSAGE
    guzzlehttp/psr7
    zendframework/zend-diactoros
    slim/slim

    View Slide

  35. 2. Server side

    View Slide

  36. View Slide

  37. START USING PSR-7 IN YOUR APP
    What about existing Symfony/Zend
    Request & Response objects?

    View Slide

  38. START USING PSR-7 IN YOUR APP
    symfony/psr-http-message-bridge
    zendframework/zend-psr7bridge

    View Slide

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

    View Slide

  40. START USING PSR-7 IN YOUR APP
    Symfony request/response object
    ⁷ ⁷ ⁷
    Zend-Diactoros request/response object
    \Psr\Http\Message\RequestInterface
    type hinted

    View Slide

  41. START USING PSR-7 IN YOUR APP
    Laravel:
    public function index(ServerRequestInterface $request){
    return $psrResponse;
    }

    View Slide

  42. START USING PSR-7 IN YOUR APP
    SlimPHP v3: routing & middleware

    View Slide

  43. Middleware
    wrapping HTTP applications

    View Slide

  44. View Slide

  45. MIDDLEWARE DEFINITION
    Session
    Logging
    Authentication
    Robots.txt file
    HTTP Cache
    Firewall
    Cors
    Throttling

    View Slide

  46. HTTP MIDDLEWARE
    PSR-15

    View Slide

  47. MIDDLEWARE DEFINITION
    interface RequestHandlerInterface
    {
    public function handle(

    ServerRequestInterface $request

    ): ResponseInterface;
    }

    View Slide

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

    View Slide

  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;
    }

    View Slide

  50. MIDDLEWARE DEFINITION
    Build your stack with:
    relay/relay
    mindplay/middleman

    View Slide

  51. Demo

    View Slide

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

    View Slide

  53. 3. Client side

    View Slide

  54. GUZZLEHTTP/GUZZLE
    composer req guzzlehttp/guzzle

    View Slide

  55. GUZZLEHTTP/GUZZLE
    composer.json
    ^6.3

    View Slide


  56. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  60. View Slide

  61. View Slide

  62. GUZZLEHTTP/GUZZLE - PSR-7
    use GuzzleHttp\Psr7\Request;
    $psrRequest = new Request(
    'GET', $uri, $headers, $body
    );

    View Slide

  63. GUZZLEHTTP/GUZZLE - PSR-7
    $client = new GuzzleHttp\Client();
    $psrResponse = $client->send($psrRequest);

    View Slide

  64. GUZZLEHTTP/GUZZLE
    Demo

    View Slide

  65. GUZZLEHTTP/GUZZLE - PROMISES
    Promises

    View Slide

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

    View Slide

  67. GUZZLEHTTP/GUZZLE - PROMISES
    use Psr\Http\Message\ResponseInterface as Res;
    $promise = $client->sendAsync($request);
    $promise->then(function (Res $response) {
    $response->getBody();
    });
    $promise->wait();

    View Slide

  68. GUZZLEHTTP/GUZZLE
    Demo

    View Slide

  69. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    Callable middlewares

    View Slide

  70. 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;
    });
    };
    }

    View Slide

  71. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    $middleware = GuzzleHttp\Middleware::log(
    $psr3Logger,
    new GuzzleHttp\MessageFormatter()
    );

    View Slide

  72. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    $stack = HandlerStack::create();
    $stack->push($middleware);
    $stack->unshift($middleware);
    $stack->remove($middleware);
    $client = new Client(['handler' => $stack]);

    View Slide

  73. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    Demo

    View Slide

  74. Decoupling HTTP Clients

    View Slide

  75. View Slide

  76. interface ClientInterface
    {

    public function sendRequest(

    RequestInterface $request

    ): ResponseInterface;
    }

    View Slide

  77. RECAP
    1. Guzzle PSR-7
    2. Promises
    3. Middleware
    4. Client abstraction

    View Slide

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

    View Slide

  79. Thank you!
    @hannesvdvreken
    #confoo

    View Slide

  80. Time for questions.
    @hannesvdvreken
    #confoo

    View Slide

  81. • 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

    View Slide