faq.rst 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. ===
  2. FAQ
  3. ===
  4. Does Guzzle require cURL?
  5. =========================
  6. No. Guzzle can use any HTTP handler to send requests. This means that Guzzle
  7. can be used with cURL, PHP's stream wrapper, sockets, and non-blocking libraries
  8. like `React <https://reactphp.org/>`_. You just need to configure an HTTP handler
  9. to use a different method of sending requests.
  10. .. note::
  11. Guzzle has historically only utilized cURL to send HTTP requests. cURL is
  12. an amazing HTTP client (arguably the best), and Guzzle will continue to use
  13. it by default when it is available. It is rare, but some developers don't
  14. have cURL installed on their systems or run into version specific issues.
  15. By allowing swappable HTTP handlers, Guzzle is now much more customizable
  16. and able to adapt to fit the needs of more developers.
  17. Can Guzzle send asynchronous requests?
  18. ======================================
  19. Yes. You can use the ``requestAsync``, ``sendAsync``, ``getAsync``,
  20. ``headAsync``, ``putAsync``, ``postAsync``, ``deleteAsync``, and ``patchAsync``
  21. methods of a client to send an asynchronous request. The client will return a
  22. ``GuzzleHttp\Promise\PromiseInterface`` object. You can chain ``then``
  23. functions off of the promise.
  24. .. code-block:: php
  25. $promise = $client->requestAsync('GET', 'http://httpbin.org/get');
  26. $promise->then(function ($response) {
  27. echo 'Got a response! ' . $response->getStatusCode();
  28. });
  29. You can force an asynchronous response to complete using the ``wait()`` method
  30. of the returned promise.
  31. .. code-block:: php
  32. $promise = $client->requestAsync('GET', 'http://httpbin.org/get');
  33. $response = $promise->wait();
  34. How can I add custom cURL options?
  35. ==================================
  36. cURL offers a huge number of `customizable options <https://www.php.net/curl_setopt>`_.
  37. While Guzzle normalizes many of these options across different handlers, there
  38. are times when you need to set custom cURL options. This can be accomplished
  39. by passing an associative array of cURL settings in the **curl** key of a
  40. request.
  41. For example, let's say you need to customize the outgoing network interface
  42. used with a client.
  43. .. code-block:: php
  44. $client->request('GET', '/', [
  45. 'curl' => [
  46. CURLOPT_INTERFACE => 'xxx.xxx.xxx.xxx'
  47. ]
  48. ]);
  49. If you use asynchronous requests with cURL multi handler and want to tweak it,
  50. additional options can be specified as an associative array in the
  51. **options** key of the ``CurlMultiHandler`` constructor.
  52. .. code-block:: php
  53. use GuzzleHttp\Client;
  54. use GuzzleHttp\HandlerStack;
  55. use GuzzleHttp\Handler\CurlMultiHandler;
  56. $client = new Client(['handler' => HandlerStack::create(new CurlMultiHandler([
  57. 'options' => [
  58. CURLMOPT_MAX_TOTAL_CONNECTIONS => 50,
  59. CURLMOPT_MAX_HOST_CONNECTIONS => 5,
  60. ]
  61. ]))]);
  62. How can I add custom stream context options?
  63. ============================================
  64. You can pass custom `stream context options <https://www.php.net/manual/en/context.php>`_
  65. using the **stream_context** key of the request option. The **stream_context**
  66. array is an associative array where each key is a PHP transport, and each value
  67. is an associative array of transport options.
  68. For example, let's say you need to customize the outgoing network interface
  69. used with a client and allow self-signed certificates.
  70. .. code-block:: php
  71. $client->request('GET', '/', [
  72. 'stream' => true,
  73. 'stream_context' => [
  74. 'ssl' => [
  75. 'allow_self_signed' => true
  76. ],
  77. 'socket' => [
  78. 'bindto' => 'xxx.xxx.xxx.xxx'
  79. ]
  80. ]
  81. ]);
  82. Why am I getting an SSL verification error?
  83. ===========================================
  84. You need to specify the path on disk to the CA bundle used by Guzzle for
  85. verifying the peer certificate. See :ref:`verify-option`.
  86. What is this Maximum function nesting error?
  87. ============================================
  88. Maximum function nesting level of '100' reached, aborting
  89. You could run into this error if you have the XDebug extension installed and
  90. you execute a lot of requests in callbacks. This error message comes
  91. specifically from the XDebug extension. PHP itself does not have a function
  92. nesting limit. Change this setting in your php.ini to increase the limit::
  93. xdebug.max_nesting_level = 1000
  94. Why am I getting a 417 error response?
  95. ======================================
  96. This can occur for a number of reasons, but if you are sending PUT, POST, or
  97. PATCH requests with an ``Expect: 100-Continue`` header, a server that does not
  98. support this header will return a 417 response. You can work around this by
  99. setting the ``expect`` request option to ``false``:
  100. .. code-block:: php
  101. $client = new GuzzleHttp\Client();
  102. // Disable the expect header on a single request
  103. $response = $client->request('PUT', '/', ['expect' => false]);
  104. // Disable the expect header on all client requests
  105. $client = new GuzzleHttp\Client(['expect' => false]);
  106. How can I track redirected requests?
  107. ====================================
  108. You can enable tracking of redirected URIs and status codes via the
  109. `track_redirects` option. Each redirected URI and status code will be stored in the
  110. ``X-Guzzle-Redirect-History`` and the ``X-Guzzle-Redirect-Status-History``
  111. header respectively.
  112. The initial request's URI and the final status code will be excluded from the results.
  113. With this in mind you should be able to easily track a request's full redirect path.
  114. For example, let's say you need to track redirects and provide both results
  115. together in a single report:
  116. .. code-block:: php
  117. // First you configure Guzzle with redirect tracking and make a request
  118. $client = new Client([
  119. RequestOptions::ALLOW_REDIRECTS => [
  120. 'max' => 10, // allow at most 10 redirects.
  121. 'strict' => true, // use "strict" RFC compliant redirects.
  122. 'referer' => true, // add a Referer header
  123. 'track_redirects' => true,
  124. ],
  125. ]);
  126. $initialRequest = '/redirect/3'; // Store the request URI for later use
  127. $response = $client->request('GET', $initialRequest); // Make your request
  128. // Retrieve both Redirect History headers
  129. $redirectUriHistory = $response->getHeader('X-Guzzle-Redirect-History')[0]; // retrieve Redirect URI history
  130. $redirectCodeHistory = $response->getHeader('X-Guzzle-Redirect-Status-History')[0]; // retrieve Redirect HTTP Status history
  131. // Add the initial URI requested to the (beginning of) URI history
  132. array_unshift($redirectUriHistory, $initialRequest);
  133. // Add the final HTTP status code to the end of HTTP response history
  134. array_push($redirectCodeHistory, $response->getStatusCode());
  135. // (Optional) Combine the items of each array into a single result set
  136. $fullRedirectReport = [];
  137. foreach ($redirectUriHistory as $key => $value) {
  138. $fullRedirectReport[$key] = ['location' => $value, 'code' => $redirectCodeHistory[$key]];
  139. }
  140. echo json_encode($fullRedirectReport);