client_handlers.rst 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. ===============
  2. Client Handlers
  3. ===============
  4. Client handlers accept a request array and return a future response array that
  5. can be used synchronously as an array or asynchronously using a promise.
  6. Built-In Handlers
  7. -----------------
  8. RingPHP comes with three built-in client handlers.
  9. Stream Handler
  10. ~~~~~~~~~~~~~~
  11. The ``GuzzleHttp\Ring\Client\StreamHandler`` uses PHP's
  12. `http stream wrapper <http://php.net/manual/en/wrappers.http.php>`_ to send
  13. requests.
  14. .. note::
  15. This handler cannot send requests concurrently.
  16. You can provide an associative array of custom stream context options to the
  17. StreamHandler using the ``stream_context`` key of the ``client`` request
  18. option.
  19. .. code-block:: php
  20. use GuzzleHttp\Ring\Client\StreamHandler;
  21. $response = $handler([
  22. 'http_method' => 'GET',
  23. 'uri' => '/',
  24. 'headers' => ['host' => ['httpbin.org']],
  25. 'client' => [
  26. 'stream_context' => [
  27. 'http' => [
  28. 'request_fulluri' => true,
  29. 'method' => 'HEAD'
  30. ],
  31. 'socket' => [
  32. 'bindto' => '127.0.0.1:0'
  33. ],
  34. 'ssl' => [
  35. 'verify_peer' => false
  36. ]
  37. ]
  38. ]
  39. ]);
  40. // Even though it's already completed, you can still use a promise
  41. $response->then(function ($response) {
  42. echo $response['status']; // 200
  43. });
  44. // Or access the response using the future interface
  45. echo $response['status']; // 200
  46. cURL Handler
  47. ~~~~~~~~~~~~
  48. The ``GuzzleHttp\Ring\Client\CurlHandler`` can be used with PHP 5.5+ to send
  49. requests using cURL easy handles. This handler is great for sending requests
  50. one at a time because the execute and select loop is implemented in C code
  51. which executes faster and consumes less memory than using PHP's
  52. ``curl_multi_*`` interface.
  53. .. note::
  54. This handler cannot send requests concurrently.
  55. When using the CurlHandler, custom curl options can be specified as an
  56. associative array of `cURL option constants <http://php.net/manual/en/curl.constants.php>`_
  57. mapping to values in the ``client`` option of a requst using the **curl** key.
  58. .. code-block:: php
  59. use GuzzleHttp\Ring\Client\CurlHandler;
  60. $handler = new CurlHandler();
  61. $request = [
  62. 'http_method' => 'GET',
  63. 'headers' => ['host' => [Server::$host]],
  64. 'client' => ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]]
  65. ];
  66. $response = $handler($request);
  67. // The response can be used directly as an array.
  68. echo $response['status']; // 200
  69. // Or, it can be used as a promise (that has already fulfilled).
  70. $response->then(function ($response) {
  71. echo $response['status']; // 200
  72. });
  73. cURL Multi Handler
  74. ~~~~~~~~~~~~~~~~~~
  75. The ``GuzzleHttp\Ring\Client\CurlMultiHandler`` transfers requests using
  76. cURL's `multi API <http://curl.haxx.se/libcurl/c/libcurl-multi.html>`_. The
  77. ``CurlMultiHandler`` is great for sending requests concurrently.
  78. .. code-block:: php
  79. use GuzzleHttp\Ring\Client\CurlMultiHandler;
  80. $handler = new CurlMultiHandler();
  81. $request = [
  82. 'http_method' => 'GET',
  83. 'headers' => ['host' => [Server::$host]]
  84. ];
  85. // this call returns a future array immediately.
  86. $response = $handler($request);
  87. // Ideally, you should use the promise API to not block.
  88. $response
  89. ->then(function ($response) {
  90. // Got the response at some point in the future
  91. echo $response['status']; // 200
  92. // Don't break the chain
  93. return $response;
  94. })->then(function ($response) {
  95. // ...
  96. });
  97. // If you really need to block, then you can use the response as an
  98. // associative array. This will block until it has completed.
  99. echo $response['status']; // 200
  100. Just like the ``CurlHandler``, the ``CurlMultiHandler`` accepts custom curl
  101. option in the ``curl`` key of the ``client`` request option.
  102. Mock Handler
  103. ~~~~~~~~~~~~
  104. The ``GuzzleHttp\Ring\Client\MockHandler`` is used to return mock responses.
  105. When constructed, the handler can be configured to return the same response
  106. array over and over, a future response, or a the evaluation of a callback
  107. function.
  108. .. code-block:: php
  109. use GuzzleHttp\Ring\Client\MockHandler;
  110. // Return a canned response.
  111. $mock = new MockHandler(['status' => 200]);
  112. $response = $mock([]);
  113. assert(200 == $response['status']);
  114. assert([] == $response['headers']);
  115. Implementing Handlers
  116. ---------------------
  117. Client handlers are just PHP callables (functions or classes that have the
  118. ``__invoke`` magic method). The callable accepts a request array and MUST
  119. return an instance of ``GuzzleHttp\Ring\Future\FutureArrayInterface`` so that
  120. the response can be used by both blocking and non-blocking consumers.
  121. Handlers need to follow a few simple rules:
  122. 1. Do not throw exceptions. If an error is encountered, return an array that
  123. contains the ``error`` key that maps to an ``\Exception`` value.
  124. 2. If the request has a ``delay`` client option, then the handler should only
  125. send the request after the specified delay time in seconds. Blocking
  126. handlers may find it convenient to just let the
  127. ``GuzzleHttp\Ring\Core::doSleep($request)`` function handle this for them.
  128. 3. Always return an instance of ``GuzzleHttp\Ring\Future\FutureArrayInterface``.
  129. 4. Complete any outstanding requests when the handler is destructed.