Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Modern HTTP handling with PHP - Meetup PHP Leuven

Modern HTTP handling with PHP - Meetup PHP Leuven

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 (madewithlove) will talk about the impact of PSR-7 on the way frameworks implement these messages, and give a few live examples.

Hannes Van De Vreken

September 03, 2015
Tweet

More Decks by Hannes Van De Vreken

Other Decks in Technology

Transcript

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

    View Slide

  2. Hi, my name is Hannes.

    View Slide

  3. madewithlove

    View Slide

  4. View Slide

  5. Highlighted packages

    View Slide

  6. 1. psr/http-message
    2. guzzlehttp/guzzle
    3. php-http/adapter

    View Slide

  7. 1. psr/http-message

    View Slide

  8. PSR/HTTP-MESSAGE
    interfaces

    View Slide

  9. PSR/HTTP-MESSAGE
    MessageInterface
    > RequestInterface
    > ResponseInterface
    UriInterface
    StreamInterface (body)

    View Slide

  10. Differences with Symfony objects:
    Interfaces, not concretions
    PSR/HTTP-MESSAGE

    View Slide

  11. Differences with Symfony objects:
    Interfaces, not concretions
    Immutable
    PSR/HTTP-MESSAGE

    View Slide

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

    View Slide

  13. PSR/HTTP-MESSAGE
    https:/
    /github.com/php-fig/http-message/tree/master/src

    View Slide

  14. 2. guzzlehttp/guzzle

    View Slide

  15. GUZZLEHTTP/GUZZLE
    composer require guzzlehttp/guzzle

    View Slide

  16. GUZZLEHTTP/GUZZLE
    composer.json
    ^6.0

    View Slide

  17. GUZZLEHTTP/GUZZLE
    composer.lock
    6.0.2

    View Slide

  18. GUZZLEHTTP/GUZZLE
    semver.mwl.be

    View Slide

  19. View Slide

  20. GUZZLEHTTP/GUZZLE
    What’s new?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  26. GUZZLEHTTP/GUZZLE - PSR-7
    "require": {
    "php": ">=5.5.0",
    "guzzlehttp/psr7": "~1.1",
    }

    View Slide

  27. GUZZLEHTTP/GUZZLE - PSR-7
    Factories to convert
    $psrRequest ⁶ $symfonyRequest
    $psrResponse ⁶ $symfonyResponse

    View Slide

  28. GUZZLEHTTP/GUZZLE - PSR-7
    Demo
    https:/
    /github.com/hannesvdvreken/psr7-demo/tree/master/1-guzzle

    View Slide

  29. GUZZLEHTTP/GUZZLE - WHAT’S NEW
    What else?

    View Slide

  30. GUZZLEHTTP/GUZZLE - PROMISES
    Promises

    View Slide

  31. GUZZLEHTTP/GUZZLE - PROMISES
    Not so new: (>=5.0.0)
    Promises

    View Slide

  32. GUZZLEHTTP/GUZZLE - PROMISES
    "require": {
    "php": ">=5.5.0",
    "guzzlehttp/psr7": "~1.1",
    "guzzlehttp/promise": "~1.0"
    }

    View Slide

  33. GUZZLEHTTP/GUZZLE - PROMISES
    $promise = $client->sendAsync($request);
    $promise->then(function ($response) {
    $response->getBody();
    });
    $promise->wait();

    View Slide

  34. GUZZLEHTTP/GUZZLE - PROMISES
    Demo
    https:/
    /github.com/hannesvdvreken/psr7-demo/tree/master/2-promise
    https:/
    /github.com/hannesvdvreken/psr7-demo/tree/master/3-multi

    View Slide

  35. GUZZLEHTTP/GUZZLE - WHAT’S NEW
    What else?

    View Slide

  36. GUZZLEHTTP/GUZZLE - EVENTING
    Previously (<4.0.0)
    symfony/event-dispatcher
    Later (>=4.0.0, <6.0.0)
    GuzzleHttp\Event\EmitterInterface
    GuzzleHttp\Event\SubscriberInterface

    View Slide

  37. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    Now (>=6.0.0)
    Callable middlewares

    View Slide

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

    View Slide

  39. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    $middleware = function ($handler) {
    return function ($request, $options)
    use ($handler) {
    // Do before
    return $handler($request, $options)
    ->then(function () {
    // Do after
    });
    };
    }

    View Slide

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

    View Slide

  41. GUZZLEHTTP/GUZZLE - MIDDLEWARES
    Demo
    https:/
    /github.com/hannesvdvreken/psr7-demo/tree/master/4-middleware

    View Slide

  42. GUZZLEHTTP/GUZZLE - WHAT ELSE
    What else?

    View Slide

  43. GUZZLEHTTP/GUZZLE - PROGRESS
    $request->getEmitter()->on(
    'progress',
    function (ProgressEvent $event) {

    }
    );

    View Slide

  44. GUZZLEHTTP/GUZZLE - PROGRESS
    Is gone!
    (>=5.0.0, <6.0.0)

    View Slide

  45. GUZZLEHTTP/GUZZLE - PROGRESS
    No progress on promise?
    Too bad!

    View Slide

  46. GUZZLEHTTP/GUZZLE - PROGRESS
    use Symfony\Component\Console
    \Helper\ProgressBar;

    View Slide

  47. GUZZLEHTTP/GUZZLE - PROGRESS
    10104/455642 [======>---------------------] 22% 14 sec/59 sec 1.4 MB

    View Slide

  48. GUZZLEHTTP/GUZZLE - PROGRESS
    15214/455642 [=========>------------------] 33% 21 sec/58 sec 2.1 MB

    View Slide

  49. GUZZLEHTTP/GUZZLE - PROGRESS
    20325/455642 [============>---------------] 43% 28 sec/59 sec 3.0 MB

    View Slide

  50. GUZZLEHTTP/GUZZLE - PROGRESS
    Roll your own

    View Slide

  51. GUZZLEHTTP/GUZZLE - PROGRESS
    $response = $client->get($uri);
    // Psr\Http\Message\StreamInterface
    $stream = $response->getBody();
    $stream->getSize();
    $stream->eof();
    $stream->read(1024);

    View Slide

  52. 3. php-http/adapter

    View Slide

  53. PHP-HTTP/ADAPTER
    Imagine you’re writing an SDK
    for GitHub/Slack/Hipchat/DO/…

    View Slide

  54. PHP-HTTP/ADAPTER
    composer require guzzlehttp/guzzle

    View Slide

  55. View Slide

  56. PHP-HTTP/ADAPTER - :CRY:
    “I already use Zend’s HTTP client!

    View Slide

  57. PHP-HTTP/ADAPTER - :CRY:
    “I can’t install Guzzle v5 ánd v6!

    View Slide

  58. PHP-HTTP/ADAPTER - SOLUTION
    Decouple from the HTTP client

    View Slide

  59. View Slide

  60. PHP-HTTP/ADAPTER - SOLUTION
    $adapter = new Adapter($guzzleClient);
    $psrRes = $adapter->sendRequest($psrReq);
    $client = new Client($adapter);
    $psrRes = $client->get($url);

    View Slide

  61. PHP-HTTP/ADAPTER - SOLUTION
    public function __construct(
    Http\Adapter\HttpAdapter $adapter
    ) {
    $this->adapter = $adapter;
    }
    public function __construct(
    Http\Client\HttpClient $client
    ) {
    $this->client = $client;
    }

    View Slide

  62. PHP-HTTP/ADAPTER - SOLUTION
    "require": {
    "php-http/adapter": "^0.1.0",
    "php-http/adapter-client": "^0.1.0",

    "php-http/adapter-implementation": "^0.1.0"
    }

    View Slide

  63. PHP-HTTP/ADAPTER - SOLUTION
    Virtual package
    "provide": {

    "php-http/adapter-implementation": "^0.1.0"
    }

    View Slide

  64. View Slide

  65. PHP-HTTP/ADAPTER - ADAPTERS
    guzzle6-adapter
    guzzle5-adapter
    guzzle4-adapter
    guzzle3-adapter
    zend2-adapter
    zend1-adapter
    cake-adapter

    View Slide

  66. PHP-HTTP/ADAPTER - ADAPTERS
    buzz-adapter
    react-adapter
    socket-adapter
    fopen-adapter
    file-get-contents-adapter
    native-curl-adapter
    pecl-adapter

    View Slide

  67. PHP-HTTP/ADAPTER - COMPOSER.JSON
    "require": {
    "guzzlehttp/guzzle": "^5.0",
    "your-awesome/sdk": "^1.0",

    "php-http/guzzle5-adapter": "^0.1.0"
    }

    View Slide

  68. PHP-HTTP/ADAPTER - COMPOSER.JSON
    "require": {
    - "guzzlehttp/guzzle": "^5.0",
    + "guzzlehttp/guzzle": "^6.0",
    "your-awesome/sdk": "^1.0",

    - "php-http/guzzle5-adapter": "^0.1.0"
    + "php-http/guzzle6-adapter": "^0.1.0"
    }

    View Slide

  69. View Slide

  70. PHP-HTTP/ADAPTER - DEMO
    Demo
    https:/
    /github.com/hannesvdvreken/psr7-demo/tree/master/5-github

    View Slide

  71. RECAP
    1. psr/http-message
    2. guzzlehttp/guzzle
    3. php-http/adapter

    View Slide

  72. Time for questions.
    @hannesvdvreken

    View Slide

  73. Thank you!
    @hannesvdvreken

    View Slide

  74. • http:/
    /mwl.be
    • 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