@@ -6,12 +6,18 @@ The HttpClient Component
6
6
========================
7
7
8
8
The HttpClient component is a low-level HTTP client with support for both
9
- PHP stream wrappers and cURL. It also provides utilities to consume APIs.
9
+ PHP stream wrappers and cURL. It provides utilities to consume APIs and
10
+ supports synchronous and asynchronous operations.
10
11
11
12
.. versionadded :: 4.3
12
13
13
14
The HttpClient component was introduced in Symfony 4.3.
14
15
16
+ .. TODO
17
+ .. tell about implementation vs abstraction
18
+ .. tell there are more options
19
+ .. tell chunked + compression are supported out of the box
20
+
15
21
Installation
16
22
------------
17
23
@@ -69,14 +75,15 @@ Enabling HTTP/2 Support
69
75
-----------------------
70
76
71
77
HTTP/2 is only supported when using the cURL-based transport and the libcurl
72
- version is >= 7.36.0. If you meet these requirements, you can enable HTTP/2
73
- explicitly via the ``http_version `` option::
78
+ version is >= 7.36.0. If you meet these requirements, HTTP/2 will be used by
79
+ default when the request protocol is ``https ``. If you need it for ``http ``,
80
+ you must enable it explicitly via the ``http_version `` option::
74
81
75
82
$httpClient = HttpClient::create(['http_version' => '2.0']);
76
83
77
- If you don't set the HTTP version explicitly, Symfony will use `` '2.0' `` only
78
- when the request protocol is `` https:// `` (and the cURL requirements mentioned
79
- earlier are met) .
84
+ Support for HTTP/2 PUSH works out of the box when libcurl >= 7.61.0 is used with
85
+ PHP >= 7.2.17 / 7.3.4: pushed responses are put into a temporary cache and are
86
+ used when a subsequent request is triggered for the corresponding URLs .
80
87
81
88
Making Requests
82
89
---------------
@@ -89,14 +96,13 @@ method to perform all kinds of HTTP requests::
89
96
$response = $httpClient->request('PUT', 'https://...');
90
97
// ...
91
98
92
- Responses are always asynchronous, so they are ready as soon as the response
93
- HTTP headers are received, instead of waiting to receive the entire response
94
- contents::
99
+ Responses are always asynchronous, so that the call to the method returns
100
+ immediately instead of waiting to receive the response::
95
101
102
+ // code execution continues immediately; it doesn't wait to receive the response
96
103
$response = $httpClient->request('GET', 'http://releases.ubuntu.com/18.04.2/ubuntu-18.04.2-desktop-amd64.iso');
97
104
98
- // code execution continues immediately; it doesn't wait to receive the response
99
- // you can get the value of any HTTP response header
105
+ // getting the response headers waits until they arrive
100
106
$contentType = $response->getHeaders()['content-type'][0];
101
107
102
108
// trying to get the response contents will block the execution until
@@ -135,8 +141,8 @@ each request (which overrides any global authentication)::
135
141
Query String Parameters
136
142
~~~~~~~~~~~~~~~~~~~~~~~
137
143
138
- You can either append them manually to the requested URL, or better, add them
139
- as an associative array to the ``query `` option::
144
+ You can either append them manually to the requested URL, or define them as an
145
+ associative array via the ``query `` option, that will be merged with the URL ::
140
146
141
147
// it makes an HTTP GET request to https://httpbin.org/get?token=...&name=...
142
148
$response = $httpClient->request('GET', 'https://httpbin.org/get', [
@@ -155,7 +161,7 @@ requests and the specific headers for each request::
155
161
156
162
// this header is added to all requests made by this client
157
163
$httpClient = HttpClient::create(['headers' => [
158
- 'Accept-Encoding ' => 'gzip ',
164
+ 'User-Agent ' => 'My Fancy App ',
159
165
]]);
160
166
161
167
// this header is only included in this request and overrides the value
@@ -170,7 +176,7 @@ Uploading Data
170
176
~~~~~~~~~~~~~~
171
177
172
178
This component provides several methods for uploading data using the ``body ``
173
- option. You can use regular strings, closures and resources and they'll be
179
+ option. You can use regular strings, closures, iterables and resources and they'll be
174
180
processed automatically when making the requests::
175
181
176
182
$response = $httpClient->request('POST', 'https://...', [
@@ -264,7 +270,7 @@ following methods::
264
270
Streaming Responses
265
271
~~~~~~~~~~~~~~~~~~~
266
272
267
- Call to the ``stream() `` method of the HTTP client to get *chunks * of the
273
+ Call the ``stream() `` method of the HTTP client to get *chunks * of the
268
274
response sequentially instead of waiting for the entire response::
269
275
270
276
$url = 'https://releases.ubuntu.com/18.04.1/ubuntu-18.04.1-desktop-amd64.iso';
@@ -286,13 +292,13 @@ response sequentially instead of waiting for the entire response::
286
292
// response chunks implement Symfony\Contracts\HttpClient\ChunkInterface
287
293
$fileHandler = fopen('/ubuntu.iso', 'w');
288
294
foreach ($httpClient->stream($response) as $chunk) {
289
- fwrite($fileHandler, $chunk->getContent(); );
295
+ fwrite($fileHandler, $chunk->getContent());
290
296
}
291
297
292
298
Handling Exceptions
293
299
~~~~~~~~~~~~~~~~~~~
294
300
295
- When the HTTP status code of the response is not in the 200-299 range (i.e. 3xx,
301
+ When the HTTP status code of the response is in the 300-599 range (i.e. 3xx,
296
302
4xx or 5xx) your code is expected to handle it. If you don't do that, the
297
303
``getHeaders() `` and ``getContent() `` methods throw an appropriate exception::
298
304
@@ -335,19 +341,15 @@ class to autoconfigure the HTTP client based on the requested URL::
335
341
use Symfony\Component\HttpClient\ScopingHttpClient;
336
342
337
343
$client = HttpClient::create();
338
- $httpClient = new ScopingHttpClient($client, [
339
- // the key is a regexp which must match the beginning of the request URL
344
+ $client = new ScopingHttpClient($client, [
345
+ // the options defined as values apply only to the URLs matching
346
+ // the regular expressions defined as keys
340
347
'https://api\.github\.com/' => [
341
348
'headers' => [
342
349
'Accept' => 'application/vnd.github.v3+json',
343
350
'Authorization' => 'token '.$githubToken,
344
351
],
345
352
],
346
-
347
- // use a '*' wildcard to apply some options to all requests
348
- '*' => [
349
- // ...
350
- ]
351
353
]);
352
354
353
355
If the request URL is relative (because you use the ``base_uri `` option), the
@@ -362,30 +364,25 @@ regular expression applied to relative URLs::
362
364
'base_uri' => 'https://api.github.com/',
363
365
// ...
364
366
],
365
-
366
- '*' => [
367
- // ...
368
- ]
369
367
],
370
368
// this is the regexp applied to all relative URLs
371
369
'https://api\.github\.com/'
372
370
);
373
371
374
- PSR-7 and PSR- 18 Compatibility
375
- ------------------------------
372
+ PSR-18 Compatibility
373
+ --------------------
376
374
377
- This component uses its own interfaces and exception classes different from the
378
- ones defined in ` PSR-7 `_ (HTTP message interfaces) and `PSR-18 `_ (HTTP Client).
379
- However, it includes the :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client `
375
+ This component uses and implements abstractions defined by the
376
+ `` symfony/contracts `` package. It also implements the `PSR-18 `_ (HTTP Client)
377
+ specifications via the :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client `
380
378
class, which is an adapter to turn a Symfony ``HttpClientInterface `` into a
381
379
PSR-18 ``ClientInterface ``.
382
380
383
- Before using it in your application, run the following commands to install the
384
- required dependencies:
381
+ To use it, you need the ``psr/http-client `` package and a `PSR-17 `_ implementation:
385
382
386
383
.. code-block :: terminal
387
384
388
- # installs the base ClientInterface
385
+ # installs the PSR-18 ClientInterface
389
386
$ composer require psr/http-client
390
387
391
388
# installs an efficient implementation of response and stream factories
@@ -437,12 +434,11 @@ If you want to define multiple HTTP clients, use this other expanded configurati
437
434
framework :
438
435
# ...
439
436
http_client :
440
- http_clients :
441
- crawler :
437
+ scoped_clients :
438
+ crawler.client :
442
439
headers : [{ 'X-Powered-By': 'ACME App' }]
443
440
http_version : ' 1.0'
444
- default :
445
- max_host_connections : 10
441
+ some_api.client :
446
442
max_redirects : 7
447
443
448
444
Injecting the HTTP Client Into Services
@@ -533,5 +529,5 @@ However, using ``MockResponse`` allows simulating chunked responses and timeouts
533
529
$mockResponse = new MockResponse($body());
534
530
535
531
.. _`cURL PHP extension` : https://php.net/curl
536
- .. _`PSR-7 ` : https://www.php-fig.org/psr/psr-7 /
532
+ .. _`PSR-17 ` : https://www.php-fig.org/psr/psr-17 /
537
533
.. _`PSR-18` : https://www.php-fig.org/psr/psr-18/
0 commit comments