1 | Guzzle Upgrade Guide
|
---|
2 | ====================
|
---|
3 |
|
---|
4 | 6.0 to 7.0
|
---|
5 | ----------
|
---|
6 |
|
---|
7 | In order to take advantage of the new features of PHP, Guzzle dropped the support
|
---|
8 | of PHP 5. The minimum supported PHP version is now PHP 7.2. Type hints and return
|
---|
9 | types for functions and methods have been added wherever possible.
|
---|
10 |
|
---|
11 | Please make sure:
|
---|
12 | - You are calling a function or a method with the correct type.
|
---|
13 | - If you extend a class of Guzzle; update all signatures on methods you override.
|
---|
14 |
|
---|
15 | #### Other backwards compatibility breaking changes
|
---|
16 |
|
---|
17 | - Class `GuzzleHttp\UriTemplate` is removed.
|
---|
18 | - Class `GuzzleHttp\Exception\SeekException` is removed.
|
---|
19 | - Classes `GuzzleHttp\Exception\BadResponseException`, `GuzzleHttp\Exception\ClientException`,
|
---|
20 | `GuzzleHttp\Exception\ServerException` can no longer be initialized with an empty
|
---|
21 | Response as argument.
|
---|
22 | - Class `GuzzleHttp\Exception\ConnectException` now extends `GuzzleHttp\Exception\TransferException`
|
---|
23 | instead of `GuzzleHttp\Exception\RequestException`.
|
---|
24 | - Function `GuzzleHttp\Exception\ConnectException::getResponse()` is removed.
|
---|
25 | - Function `GuzzleHttp\Exception\ConnectException::hasResponse()` is removed.
|
---|
26 | - Constant `GuzzleHttp\ClientInterface::VERSION` is removed. Added `GuzzleHttp\ClientInterface::MAJOR_VERSION` instead.
|
---|
27 | - Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed.
|
---|
28 | Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative.
|
---|
29 | - Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed.
|
---|
30 | - Request option `exceptions` is removed. Please use `http_errors`.
|
---|
31 | - Request option `save_to` is removed. Please use `sink`.
|
---|
32 | - Pool option `pool_size` is removed. Please use `concurrency`.
|
---|
33 | - We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility.
|
---|
34 | - The `get`, `head`, `put`, `post`, `patch`, `delete`, `getAsync`, `headAsync`, `putAsync`, `postAsync`, `patchAsync`, and `deleteAsync` methods are now implemented as genuine methods on `GuzzleHttp\Client`, with strong typing. The original `__call` implementation remains unchanged for now, for maximum backwards compatibility, but won't be invoked under normal operation.
|
---|
35 | - The `log` middleware will log the errors with level `error` instead of `notice`
|
---|
36 | - Support for international domain names (IDN) is now disabled by default, and enabling it requires installing ext-intl, linked against a modern version of the C library (ICU 4.6 or higher).
|
---|
37 |
|
---|
38 | #### Native functions calls
|
---|
39 |
|
---|
40 | All internal native functions calls of Guzzle are now prefixed with a slash. This
|
---|
41 | change makes it impossible for method overloading by other libraries or applications.
|
---|
42 | Example:
|
---|
43 |
|
---|
44 | ```php
|
---|
45 | // Before:
|
---|
46 | curl_version();
|
---|
47 |
|
---|
48 | // After:
|
---|
49 | \curl_version();
|
---|
50 | ```
|
---|
51 |
|
---|
52 | For the full diff you can check [here](https://github.com/guzzle/guzzle/compare/6.5.4..master).
|
---|
53 |
|
---|
54 | 5.0 to 6.0
|
---|
55 | ----------
|
---|
56 |
|
---|
57 | Guzzle now uses [PSR-7](https://www.php-fig.org/psr/psr-7/) for HTTP messages.
|
---|
58 | Due to the fact that these messages are immutable, this prompted a refactoring
|
---|
59 | of Guzzle to use a middleware based system rather than an event system. Any
|
---|
60 | HTTP message interaction (e.g., `GuzzleHttp\Message\Request`) need to be
|
---|
61 | updated to work with the new immutable PSR-7 request and response objects. Any
|
---|
62 | event listeners or subscribers need to be updated to become middleware
|
---|
63 | functions that wrap handlers (or are injected into a
|
---|
64 | `GuzzleHttp\HandlerStack`).
|
---|
65 |
|
---|
66 | - Removed `GuzzleHttp\BatchResults`
|
---|
67 | - Removed `GuzzleHttp\Collection`
|
---|
68 | - Removed `GuzzleHttp\HasDataTrait`
|
---|
69 | - Removed `GuzzleHttp\ToArrayInterface`
|
---|
70 | - The `guzzlehttp/streams` dependency has been removed. Stream functionality
|
---|
71 | is now present in the `GuzzleHttp\Psr7` namespace provided by the
|
---|
72 | `guzzlehttp/psr7` package.
|
---|
73 | - Guzzle no longer uses ReactPHP promises and now uses the
|
---|
74 | `guzzlehttp/promises` library. We use a custom promise library for three
|
---|
75 | significant reasons:
|
---|
76 | 1. React promises (at the time of writing this) are recursive. Promise
|
---|
77 | chaining and promise resolution will eventually blow the stack. Guzzle
|
---|
78 | promises are not recursive as they use a sort of trampolining technique.
|
---|
79 | Note: there has been movement in the React project to modify promises to
|
---|
80 | no longer utilize recursion.
|
---|
81 | 2. Guzzle needs to have the ability to synchronously block on a promise to
|
---|
82 | wait for a result. Guzzle promises allows this functionality (and does
|
---|
83 | not require the use of recursion).
|
---|
84 | 3. Because we need to be able to wait on a result, doing so using React
|
---|
85 | promises requires wrapping react promises with RingPHP futures. This
|
---|
86 | overhead is no longer needed, reducing stack sizes, reducing complexity,
|
---|
87 | and improving performance.
|
---|
88 | - `GuzzleHttp\Mimetypes` has been moved to a function in
|
---|
89 | `GuzzleHttp\Psr7\mimetype_from_extension` and
|
---|
90 | `GuzzleHttp\Psr7\mimetype_from_filename`.
|
---|
91 | - `GuzzleHttp\Query` and `GuzzleHttp\QueryParser` have been removed. Query
|
---|
92 | strings must now be passed into request objects as strings, or provided to
|
---|
93 | the `query` request option when creating requests with clients. The `query`
|
---|
94 | option uses PHP's `http_build_query` to convert an array to a string. If you
|
---|
95 | need a different serialization technique, you will need to pass the query
|
---|
96 | string in as a string. There are a couple helper functions that will make
|
---|
97 | working with query strings easier: `GuzzleHttp\Psr7\parse_query` and
|
---|
98 | `GuzzleHttp\Psr7\build_query`.
|
---|
99 | - Guzzle no longer has a dependency on RingPHP. Due to the use of a middleware
|
---|
100 | system based on PSR-7, using RingPHP and it's middleware system as well adds
|
---|
101 | more complexity than the benefits it provides. All HTTP handlers that were
|
---|
102 | present in RingPHP have been modified to work directly with PSR-7 messages
|
---|
103 | and placed in the `GuzzleHttp\Handler` namespace. This significantly reduces
|
---|
104 | complexity in Guzzle, removes a dependency, and improves performance. RingPHP
|
---|
105 | will be maintained for Guzzle 5 support, but will no longer be a part of
|
---|
106 | Guzzle 6.
|
---|
107 | - As Guzzle now uses a middleware based systems the event system and RingPHP
|
---|
108 | integration has been removed. Note: while the event system has been removed,
|
---|
109 | it is possible to add your own type of event system that is powered by the
|
---|
110 | middleware system.
|
---|
111 | - Removed the `Event` namespace.
|
---|
112 | - Removed the `Subscriber` namespace.
|
---|
113 | - Removed `Transaction` class
|
---|
114 | - Removed `RequestFsm`
|
---|
115 | - Removed `RingBridge`
|
---|
116 | - `GuzzleHttp\Subscriber\Cookie` is now provided by
|
---|
117 | `GuzzleHttp\Middleware::cookies`
|
---|
118 | - `GuzzleHttp\Subscriber\HttpError` is now provided by
|
---|
119 | `GuzzleHttp\Middleware::httpError`
|
---|
120 | - `GuzzleHttp\Subscriber\History` is now provided by
|
---|
121 | `GuzzleHttp\Middleware::history`
|
---|
122 | - `GuzzleHttp\Subscriber\Mock` is now provided by
|
---|
123 | `GuzzleHttp\Handler\MockHandler`
|
---|
124 | - `GuzzleHttp\Subscriber\Prepare` is now provided by
|
---|
125 | `GuzzleHttp\PrepareBodyMiddleware`
|
---|
126 | - `GuzzleHttp\Subscriber\Redirect` is now provided by
|
---|
127 | `GuzzleHttp\RedirectMiddleware`
|
---|
128 | - Guzzle now uses `Psr\Http\Message\UriInterface` (implements in
|
---|
129 | `GuzzleHttp\Psr7\Uri`) for URI support. `GuzzleHttp\Url` is now gone.
|
---|
130 | - Static functions in `GuzzleHttp\Utils` have been moved to namespaced
|
---|
131 | functions under the `GuzzleHttp` namespace. This requires either a Composer
|
---|
132 | based autoloader or you to include functions.php.
|
---|
133 | - `GuzzleHttp\ClientInterface::getDefaultOption` has been renamed to
|
---|
134 | `GuzzleHttp\ClientInterface::getConfig`.
|
---|
135 | - `GuzzleHttp\ClientInterface::setDefaultOption` has been removed.
|
---|
136 | - The `json` and `xml` methods of response objects has been removed. With the
|
---|
137 | migration to strictly adhering to PSR-7 as the interface for Guzzle messages,
|
---|
138 | adding methods to message interfaces would actually require Guzzle messages
|
---|
139 | to extend from PSR-7 messages rather then work with them directly.
|
---|
140 |
|
---|
141 | ## Migrating to middleware
|
---|
142 |
|
---|
143 | The change to PSR-7 unfortunately required significant refactoring to Guzzle
|
---|
144 | due to the fact that PSR-7 messages are immutable. Guzzle 5 relied on an event
|
---|
145 | system from plugins. The event system relied on mutability of HTTP messages and
|
---|
146 | side effects in order to work. With immutable messages, you have to change your
|
---|
147 | workflow to become more about either returning a value (e.g., functional
|
---|
148 | middlewares) or setting a value on an object. Guzzle v6 has chosen the
|
---|
149 | functional middleware approach.
|
---|
150 |
|
---|
151 | Instead of using the event system to listen for things like the `before` event,
|
---|
152 | you now create a stack based middleware function that intercepts a request on
|
---|
153 | the way in and the promise of the response on the way out. This is a much
|
---|
154 | simpler and more predictable approach than the event system and works nicely
|
---|
155 | with PSR-7 middleware. Due to the use of promises, the middleware system is
|
---|
156 | also asynchronous.
|
---|
157 |
|
---|
158 | v5:
|
---|
159 |
|
---|
160 | ```php
|
---|
161 | use GuzzleHttp\Event\BeforeEvent;
|
---|
162 | $client = new GuzzleHttp\Client();
|
---|
163 | // Get the emitter and listen to the before event.
|
---|
164 | $client->getEmitter()->on('before', function (BeforeEvent $e) {
|
---|
165 | // Guzzle v5 events relied on mutation
|
---|
166 | $e->getRequest()->setHeader('X-Foo', 'Bar');
|
---|
167 | });
|
---|
168 | ```
|
---|
169 |
|
---|
170 | v6:
|
---|
171 |
|
---|
172 | In v6, you can modify the request before it is sent using the `mapRequest`
|
---|
173 | middleware. The idiomatic way in v6 to modify the request/response lifecycle is
|
---|
174 | to setup a handler middleware stack up front and inject the handler into a
|
---|
175 | client.
|
---|
176 |
|
---|
177 | ```php
|
---|
178 | use GuzzleHttp\Middleware;
|
---|
179 | // Create a handler stack that has all of the default middlewares attached
|
---|
180 | $handler = GuzzleHttp\HandlerStack::create();
|
---|
181 | // Push the handler onto the handler stack
|
---|
182 | $handler->push(Middleware::mapRequest(function (RequestInterface $request) {
|
---|
183 | // Notice that we have to return a request object
|
---|
184 | return $request->withHeader('X-Foo', 'Bar');
|
---|
185 | }));
|
---|
186 | // Inject the handler into the client
|
---|
187 | $client = new GuzzleHttp\Client(['handler' => $handler]);
|
---|
188 | ```
|
---|
189 |
|
---|
190 | ## POST Requests
|
---|
191 |
|
---|
192 | This version added the [`form_params`](https://docs.guzzlephp.org/en/latest/request-options.html#form_params)
|
---|
193 | and `multipart` request options. `form_params` is an associative array of
|
---|
194 | strings or array of strings and is used to serialize an
|
---|
195 | `application/x-www-form-urlencoded` POST request. The
|
---|
196 | [`multipart`](https://docs.guzzlephp.org/en/latest/request-options.html#multipart)
|
---|
197 | option is now used to send a multipart/form-data POST request.
|
---|
198 |
|
---|
199 | `GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add
|
---|
200 | POST files to a multipart/form-data request.
|
---|
201 |
|
---|
202 | The `body` option no longer accepts an array to send POST requests. Please use
|
---|
203 | `multipart` or `form_params` instead.
|
---|
204 |
|
---|
205 | The `base_url` option has been renamed to `base_uri`.
|
---|
206 |
|
---|
207 | 4.x to 5.0
|
---|
208 | ----------
|
---|
209 |
|
---|
210 | ## Rewritten Adapter Layer
|
---|
211 |
|
---|
212 | Guzzle now uses [RingPHP](https://ringphp.readthedocs.org/en/latest) to send
|
---|
213 | HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor
|
---|
214 | is still supported, but it has now been renamed to `handler`. Instead of
|
---|
215 | passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP
|
---|
216 | `callable` that follows the RingPHP specification.
|
---|
217 |
|
---|
218 | ## Removed Fluent Interfaces
|
---|
219 |
|
---|
220 | [Fluent interfaces were removed](https://ocramius.github.io/blog/fluent-interfaces-are-evil/)
|
---|
221 | from the following classes:
|
---|
222 |
|
---|
223 | - `GuzzleHttp\Collection`
|
---|
224 | - `GuzzleHttp\Url`
|
---|
225 | - `GuzzleHttp\Query`
|
---|
226 | - `GuzzleHttp\Post\PostBody`
|
---|
227 | - `GuzzleHttp\Cookie\SetCookie`
|
---|
228 |
|
---|
229 | ## Removed functions.php
|
---|
230 |
|
---|
231 | Removed "functions.php", so that Guzzle is truly PSR-4 compliant. The following
|
---|
232 | functions can be used as replacements.
|
---|
233 |
|
---|
234 | - `GuzzleHttp\json_decode` -> `GuzzleHttp\Utils::jsonDecode`
|
---|
235 | - `GuzzleHttp\get_path` -> `GuzzleHttp\Utils::getPath`
|
---|
236 | - `GuzzleHttp\Utils::setPath` -> `GuzzleHttp\set_path`
|
---|
237 | - `GuzzleHttp\Pool::batch` -> `GuzzleHttp\batch`. This function is, however,
|
---|
238 | deprecated in favor of using `GuzzleHttp\Pool::batch()`.
|
---|
239 |
|
---|
240 | The "procedural" global client has been removed with no replacement (e.g.,
|
---|
241 | `GuzzleHttp\get()`, `GuzzleHttp\post()`, etc.). Use a `GuzzleHttp\Client`
|
---|
242 | object as a replacement.
|
---|
243 |
|
---|
244 | ## `throwImmediately` has been removed
|
---|
245 |
|
---|
246 | The concept of "throwImmediately" has been removed from exceptions and error
|
---|
247 | events. This control mechanism was used to stop a transfer of concurrent
|
---|
248 | requests from completing. This can now be handled by throwing the exception or
|
---|
249 | by cancelling a pool of requests or each outstanding future request
|
---|
250 | individually.
|
---|
251 |
|
---|
252 | ## headers event has been removed
|
---|
253 |
|
---|
254 | Removed the "headers" event. This event was only useful for changing the
|
---|
255 | body a response once the headers of the response were known. You can implement
|
---|
256 | a similar behavior in a number of ways. One example might be to use a
|
---|
257 | FnStream that has access to the transaction being sent. For example, when the
|
---|
258 | first byte is written, you could check if the response headers match your
|
---|
259 | expectations, and if so, change the actual stream body that is being
|
---|
260 | written to.
|
---|
261 |
|
---|
262 | ## Updates to HTTP Messages
|
---|
263 |
|
---|
264 | Removed the `asArray` parameter from
|
---|
265 | `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header
|
---|
266 | value as an array, then use the newly added `getHeaderAsArray()` method of
|
---|
267 | `MessageInterface`. This change makes the Guzzle interfaces compatible with
|
---|
268 | the PSR-7 interfaces.
|
---|
269 |
|
---|
270 | 3.x to 4.0
|
---|
271 | ----------
|
---|
272 |
|
---|
273 | ## Overarching changes:
|
---|
274 |
|
---|
275 | - Now requires PHP 5.4 or greater.
|
---|
276 | - No longer requires cURL to send requests.
|
---|
277 | - Guzzle no longer wraps every exception it throws. Only exceptions that are
|
---|
278 | recoverable are now wrapped by Guzzle.
|
---|
279 | - Various namespaces have been removed or renamed.
|
---|
280 | - No longer requiring the Symfony EventDispatcher. A custom event dispatcher
|
---|
281 | based on the Symfony EventDispatcher is
|
---|
282 | now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant
|
---|
283 | speed and functionality improvements).
|
---|
284 |
|
---|
285 | Changes per Guzzle 3.x namespace are described below.
|
---|
286 |
|
---|
287 | ## Batch
|
---|
288 |
|
---|
289 | The `Guzzle\Batch` namespace has been removed. This is best left to
|
---|
290 | third-parties to implement on top of Guzzle's core HTTP library.
|
---|
291 |
|
---|
292 | ## Cache
|
---|
293 |
|
---|
294 | The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement
|
---|
295 | has been implemented yet, but hoping to utilize a PSR cache interface).
|
---|
296 |
|
---|
297 | ## Common
|
---|
298 |
|
---|
299 | - Removed all of the wrapped exceptions. It's better to use the standard PHP
|
---|
300 | library for unrecoverable exceptions.
|
---|
301 | - `FromConfigInterface` has been removed.
|
---|
302 | - `Guzzle\Common\Version` has been removed. The VERSION constant can be found
|
---|
303 | at `GuzzleHttp\ClientInterface::VERSION`.
|
---|
304 |
|
---|
305 | ### Collection
|
---|
306 |
|
---|
307 | - `getAll` has been removed. Use `toArray` to convert a collection to an array.
|
---|
308 | - `inject` has been removed.
|
---|
309 | - `keySearch` has been removed.
|
---|
310 | - `getPath` no longer supports wildcard expressions. Use something better like
|
---|
311 | JMESPath for this.
|
---|
312 | - `setPath` now supports appending to an existing array via the `[]` notation.
|
---|
313 |
|
---|
314 | ### Events
|
---|
315 |
|
---|
316 | Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses
|
---|
317 | `GuzzleHttp\Event\Emitter`.
|
---|
318 |
|
---|
319 | - `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by
|
---|
320 | `GuzzleHttp\Event\EmitterInterface`.
|
---|
321 | - `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by
|
---|
322 | `GuzzleHttp\Event\Emitter`.
|
---|
323 | - `Symfony\Component\EventDispatcher\Event` is replaced by
|
---|
324 | `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in
|
---|
325 | `GuzzleHttp\Event\EventInterface`.
|
---|
326 | - `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and
|
---|
327 | `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the
|
---|
328 | event emitter of a request, client, etc. now uses the `getEmitter` method
|
---|
329 | rather than the `getDispatcher` method.
|
---|
330 |
|
---|
331 | #### Emitter
|
---|
332 |
|
---|
333 | - Use the `once()` method to add a listener that automatically removes itself
|
---|
334 | the first time it is invoked.
|
---|
335 | - Use the `listeners()` method to retrieve a list of event listeners rather than
|
---|
336 | the `getListeners()` method.
|
---|
337 | - Use `emit()` instead of `dispatch()` to emit an event from an emitter.
|
---|
338 | - Use `attach()` instead of `addSubscriber()` and `detach()` instead of
|
---|
339 | `removeSubscriber()`.
|
---|
340 |
|
---|
341 | ```php
|
---|
342 | $mock = new Mock();
|
---|
343 | // 3.x
|
---|
344 | $request->getEventDispatcher()->addSubscriber($mock);
|
---|
345 | $request->getEventDispatcher()->removeSubscriber($mock);
|
---|
346 | // 4.x
|
---|
347 | $request->getEmitter()->attach($mock);
|
---|
348 | $request->getEmitter()->detach($mock);
|
---|
349 | ```
|
---|
350 |
|
---|
351 | Use the `on()` method to add a listener rather than the `addListener()` method.
|
---|
352 |
|
---|
353 | ```php
|
---|
354 | // 3.x
|
---|
355 | $request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } );
|
---|
356 | // 4.x
|
---|
357 | $request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } );
|
---|
358 | ```
|
---|
359 |
|
---|
360 | ## Http
|
---|
361 |
|
---|
362 | ### General changes
|
---|
363 |
|
---|
364 | - The cacert.pem certificate has been moved to `src/cacert.pem`.
|
---|
365 | - Added the concept of adapters that are used to transfer requests over the
|
---|
366 | wire.
|
---|
367 | - Simplified the event system.
|
---|
368 | - Sending requests in parallel is still possible, but batching is no longer a
|
---|
369 | concept of the HTTP layer. Instead, you must use the `complete` and `error`
|
---|
370 | events to asynchronously manage parallel request transfers.
|
---|
371 | - `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`.
|
---|
372 | - `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`.
|
---|
373 | - QueryAggregators have been rewritten so that they are simply callable
|
---|
374 | functions.
|
---|
375 | - `GuzzleHttp\StaticClient` has been removed. Use the functions provided in
|
---|
376 | `functions.php` for an easy to use static client instance.
|
---|
377 | - Exceptions in `GuzzleHttp\Exception` have been updated to all extend from
|
---|
378 | `GuzzleHttp\Exception\TransferException`.
|
---|
379 |
|
---|
380 | ### Client
|
---|
381 |
|
---|
382 | Calling methods like `get()`, `post()`, `head()`, etc. no longer create and
|
---|
383 | return a request, but rather creates a request, sends the request, and returns
|
---|
384 | the response.
|
---|
385 |
|
---|
386 | ```php
|
---|
387 | // 3.0
|
---|
388 | $request = $client->get('/');
|
---|
389 | $response = $request->send();
|
---|
390 |
|
---|
391 | // 4.0
|
---|
392 | $response = $client->get('/');
|
---|
393 |
|
---|
394 | // or, to mirror the previous behavior
|
---|
395 | $request = $client->createRequest('GET', '/');
|
---|
396 | $response = $client->send($request);
|
---|
397 | ```
|
---|
398 |
|
---|
399 | `GuzzleHttp\ClientInterface` has changed.
|
---|
400 |
|
---|
401 | - The `send` method no longer accepts more than one request. Use `sendAll` to
|
---|
402 | send multiple requests in parallel.
|
---|
403 | - `setUserAgent()` has been removed. Use a default request option instead. You
|
---|
404 | could, for example, do something like:
|
---|
405 | `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`.
|
---|
406 | - `setSslVerification()` has been removed. Use default request options instead,
|
---|
407 | like `$client->setConfig('defaults/verify', true)`.
|
---|
408 |
|
---|
409 | `GuzzleHttp\Client` has changed.
|
---|
410 |
|
---|
411 | - The constructor now accepts only an associative array. You can include a
|
---|
412 | `base_url` string or array to use a URI template as the base URL of a client.
|
---|
413 | You can also specify a `defaults` key that is an associative array of default
|
---|
414 | request options. You can pass an `adapter` to use a custom adapter,
|
---|
415 | `batch_adapter` to use a custom adapter for sending requests in parallel, or
|
---|
416 | a `message_factory` to change the factory used to create HTTP requests and
|
---|
417 | responses.
|
---|
418 | - The client no longer emits a `client.create_request` event.
|
---|
419 | - Creating requests with a client no longer automatically utilize a URI
|
---|
420 | template. You must pass an array into a creational method (e.g.,
|
---|
421 | `createRequest`, `get`, `put`, etc.) in order to expand a URI template.
|
---|
422 |
|
---|
423 | ### Messages
|
---|
424 |
|
---|
425 | Messages no longer have references to their counterparts (i.e., a request no
|
---|
426 | longer has a reference to it's response, and a response no loger has a
|
---|
427 | reference to its request). This association is now managed through a
|
---|
428 | `GuzzleHttp\Adapter\TransactionInterface` object. You can get references to
|
---|
429 | these transaction objects using request events that are emitted over the
|
---|
430 | lifecycle of a request.
|
---|
431 |
|
---|
432 | #### Requests with a body
|
---|
433 |
|
---|
434 | - `GuzzleHttp\Message\EntityEnclosingRequest` and
|
---|
435 | `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The
|
---|
436 | separation between requests that contain a body and requests that do not
|
---|
437 | contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface`
|
---|
438 | handles both use cases.
|
---|
439 | - Any method that previously accepts a `GuzzleHttp\Response` object now accept a
|
---|
440 | `GuzzleHttp\Message\ResponseInterface`.
|
---|
441 | - `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to
|
---|
442 | `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create
|
---|
443 | both requests and responses and is implemented in
|
---|
444 | `GuzzleHttp\Message\MessageFactory`.
|
---|
445 | - POST field and file methods have been removed from the request object. You
|
---|
446 | must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface`
|
---|
447 | to control the format of a POST body. Requests that are created using a
|
---|
448 | standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use
|
---|
449 | a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if
|
---|
450 | the method is POST and no body is provided.
|
---|
451 |
|
---|
452 | ```php
|
---|
453 | $request = $client->createRequest('POST', '/');
|
---|
454 | $request->getBody()->setField('foo', 'bar');
|
---|
455 | $request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r')));
|
---|
456 | ```
|
---|
457 |
|
---|
458 | #### Headers
|
---|
459 |
|
---|
460 | - `GuzzleHttp\Message\Header` has been removed. Header values are now simply
|
---|
461 | represented by an array of values or as a string. Header values are returned
|
---|
462 | as a string by default when retrieving a header value from a message. You can
|
---|
463 | pass an optional argument of `true` to retrieve a header value as an array
|
---|
464 | of strings instead of a single concatenated string.
|
---|
465 | - `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to
|
---|
466 | `GuzzleHttp\Post`. This interface has been simplified and now allows the
|
---|
467 | addition of arbitrary headers.
|
---|
468 | - Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most
|
---|
469 | of the custom headers are now handled separately in specific
|
---|
470 | subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has
|
---|
471 | been updated to properly handle headers that contain parameters (like the
|
---|
472 | `Link` header).
|
---|
473 |
|
---|
474 | #### Responses
|
---|
475 |
|
---|
476 | - `GuzzleHttp\Message\Response::getInfo()` and
|
---|
477 | `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event
|
---|
478 | system to retrieve this type of information.
|
---|
479 | - `GuzzleHttp\Message\Response::getRawHeaders()` has been removed.
|
---|
480 | - `GuzzleHttp\Message\Response::getMessage()` has been removed.
|
---|
481 | - `GuzzleHttp\Message\Response::calculateAge()` and other cache specific
|
---|
482 | methods have moved to the CacheSubscriber.
|
---|
483 | - Header specific helper functions like `getContentMd5()` have been removed.
|
---|
484 | Just use `getHeader('Content-MD5')` instead.
|
---|
485 | - `GuzzleHttp\Message\Response::setRequest()` and
|
---|
486 | `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event
|
---|
487 | system to work with request and response objects as a transaction.
|
---|
488 | - `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the
|
---|
489 | Redirect subscriber instead.
|
---|
490 | - `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have
|
---|
491 | been removed. Use `getStatusCode()` instead.
|
---|
492 |
|
---|
493 | #### Streaming responses
|
---|
494 |
|
---|
495 | Streaming requests can now be created by a client directly, returning a
|
---|
496 | `GuzzleHttp\Message\ResponseInterface` object that contains a body stream
|
---|
497 | referencing an open PHP HTTP stream.
|
---|
498 |
|
---|
499 | ```php
|
---|
500 | // 3.0
|
---|
501 | use Guzzle\Stream\PhpStreamRequestFactory;
|
---|
502 | $request = $client->get('/');
|
---|
503 | $factory = new PhpStreamRequestFactory();
|
---|
504 | $stream = $factory->fromRequest($request);
|
---|
505 | $data = $stream->read(1024);
|
---|
506 |
|
---|
507 | // 4.0
|
---|
508 | $response = $client->get('/', ['stream' => true]);
|
---|
509 | // Read some data off of the stream in the response body
|
---|
510 | $data = $response->getBody()->read(1024);
|
---|
511 | ```
|
---|
512 |
|
---|
513 | #### Redirects
|
---|
514 |
|
---|
515 | The `configureRedirects()` method has been removed in favor of a
|
---|
516 | `allow_redirects` request option.
|
---|
517 |
|
---|
518 | ```php
|
---|
519 | // Standard redirects with a default of a max of 5 redirects
|
---|
520 | $request = $client->createRequest('GET', '/', ['allow_redirects' => true]);
|
---|
521 |
|
---|
522 | // Strict redirects with a custom number of redirects
|
---|
523 | $request = $client->createRequest('GET', '/', [
|
---|
524 | 'allow_redirects' => ['max' => 5, 'strict' => true]
|
---|
525 | ]);
|
---|
526 | ```
|
---|
527 |
|
---|
528 | #### EntityBody
|
---|
529 |
|
---|
530 | EntityBody interfaces and classes have been removed or moved to
|
---|
531 | `GuzzleHttp\Stream`. All classes and interfaces that once required
|
---|
532 | `GuzzleHttp\EntityBodyInterface` now require
|
---|
533 | `GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no
|
---|
534 | longer uses `GuzzleHttp\EntityBody::factory` but now uses
|
---|
535 | `GuzzleHttp\Stream\Stream::factory` or even better:
|
---|
536 | `GuzzleHttp\Stream\create()`.
|
---|
537 |
|
---|
538 | - `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface`
|
---|
539 | - `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream`
|
---|
540 | - `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream`
|
---|
541 | - `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream`
|
---|
542 | - `Guzzle\Http\IoEmittyinEntityBody` has been removed.
|
---|
543 |
|
---|
544 | #### Request lifecycle events
|
---|
545 |
|
---|
546 | Requests previously submitted a large number of requests. The number of events
|
---|
547 | emitted over the lifecycle of a request has been significantly reduced to make
|
---|
548 | it easier to understand how to extend the behavior of a request. All events
|
---|
549 | emitted during the lifecycle of a request now emit a custom
|
---|
550 | `GuzzleHttp\Event\EventInterface` object that contains context providing
|
---|
551 | methods and a way in which to modify the transaction at that specific point in
|
---|
552 | time (e.g., intercept the request and set a response on the transaction).
|
---|
553 |
|
---|
554 | - `request.before_send` has been renamed to `before` and now emits a
|
---|
555 | `GuzzleHttp\Event\BeforeEvent`
|
---|
556 | - `request.complete` has been renamed to `complete` and now emits a
|
---|
557 | `GuzzleHttp\Event\CompleteEvent`.
|
---|
558 | - `request.sent` has been removed. Use `complete`.
|
---|
559 | - `request.success` has been removed. Use `complete`.
|
---|
560 | - `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`.
|
---|
561 | - `request.exception` has been removed. Use `error`.
|
---|
562 | - `request.receive.status_line` has been removed.
|
---|
563 | - `curl.callback.progress` has been removed. Use a custom `StreamInterface` to
|
---|
564 | maintain a status update.
|
---|
565 | - `curl.callback.write` has been removed. Use a custom `StreamInterface` to
|
---|
566 | intercept writes.
|
---|
567 | - `curl.callback.read` has been removed. Use a custom `StreamInterface` to
|
---|
568 | intercept reads.
|
---|
569 |
|
---|
570 | `headers` is a new event that is emitted after the response headers of a
|
---|
571 | request have been received before the body of the response is downloaded. This
|
---|
572 | event emits a `GuzzleHttp\Event\HeadersEvent`.
|
---|
573 |
|
---|
574 | You can intercept a request and inject a response using the `intercept()` event
|
---|
575 | of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and
|
---|
576 | `GuzzleHttp\Event\ErrorEvent` event.
|
---|
577 |
|
---|
578 | See: https://docs.guzzlephp.org/en/latest/events.html
|
---|
579 |
|
---|
580 | ## Inflection
|
---|
581 |
|
---|
582 | The `Guzzle\Inflection` namespace has been removed. This is not a core concern
|
---|
583 | of Guzzle.
|
---|
584 |
|
---|
585 | ## Iterator
|
---|
586 |
|
---|
587 | The `Guzzle\Iterator` namespace has been removed.
|
---|
588 |
|
---|
589 | - `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and
|
---|
590 | `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of
|
---|
591 | Guzzle itself.
|
---|
592 | - `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent
|
---|
593 | class is shipped with PHP 5.4.
|
---|
594 | - `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because
|
---|
595 | it's easier to just wrap an iterator in a generator that maps values.
|
---|
596 |
|
---|
597 | For a replacement of these iterators, see https://github.com/nikic/iter
|
---|
598 |
|
---|
599 | ## Log
|
---|
600 |
|
---|
601 | The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The
|
---|
602 | `Guzzle\Log` namespace has been removed. Guzzle now relies on
|
---|
603 | `Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been
|
---|
604 | moved to `GuzzleHttp\Subscriber\Log\Formatter`.
|
---|
605 |
|
---|
606 | ## Parser
|
---|
607 |
|
---|
608 | The `Guzzle\Parser` namespace has been removed. This was previously used to
|
---|
609 | make it possible to plug in custom parsers for cookies, messages, URI
|
---|
610 | templates, and URLs; however, this level of complexity is not needed in Guzzle
|
---|
611 | so it has been removed.
|
---|
612 |
|
---|
613 | - Cookie: Cookie parsing logic has been moved to
|
---|
614 | `GuzzleHttp\Cookie\SetCookie::fromString`.
|
---|
615 | - Message: Message parsing logic for both requests and responses has been moved
|
---|
616 | to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only
|
---|
617 | used in debugging or deserializing messages, so it doesn't make sense for
|
---|
618 | Guzzle as a library to add this level of complexity to parsing messages.
|
---|
619 | - UriTemplate: URI template parsing has been moved to
|
---|
620 | `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL
|
---|
621 | URI template library if it is installed.
|
---|
622 | - Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously
|
---|
623 | it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary,
|
---|
624 | then developers are free to subclass `GuzzleHttp\Url`.
|
---|
625 |
|
---|
626 | ## Plugin
|
---|
627 |
|
---|
628 | The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`.
|
---|
629 | Several plugins are shipping with the core Guzzle library under this namespace.
|
---|
630 |
|
---|
631 | - `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar
|
---|
632 | code has moved to `GuzzleHttp\Cookie`.
|
---|
633 | - `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin.
|
---|
634 | - `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is
|
---|
635 | received.
|
---|
636 | - `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin.
|
---|
637 | - `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before
|
---|
638 | sending. This subscriber is attached to all requests by default.
|
---|
639 | - `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin.
|
---|
640 |
|
---|
641 | The following plugins have been removed (third-parties are free to re-implement
|
---|
642 | these if needed):
|
---|
643 |
|
---|
644 | - `GuzzleHttp\Plugin\Async` has been removed.
|
---|
645 | - `GuzzleHttp\Plugin\CurlAuth` has been removed.
|
---|
646 | - `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This
|
---|
647 | functionality should instead be implemented with event listeners that occur
|
---|
648 | after normal response parsing occurs in the guzzle/command package.
|
---|
649 |
|
---|
650 | The following plugins are not part of the core Guzzle package, but are provided
|
---|
651 | in separate repositories:
|
---|
652 |
|
---|
653 | - `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be much simpler
|
---|
654 | to build custom retry policies using simple functions rather than various
|
---|
655 | chained classes. See: https://github.com/guzzle/retry-subscriber
|
---|
656 | - `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to
|
---|
657 | https://github.com/guzzle/cache-subscriber
|
---|
658 | - `Guzzle\Http\Plugin\Log\LogPlugin` has moved to
|
---|
659 | https://github.com/guzzle/log-subscriber
|
---|
660 | - `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to
|
---|
661 | https://github.com/guzzle/message-integrity-subscriber
|
---|
662 | - `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to
|
---|
663 | `GuzzleHttp\Subscriber\MockSubscriber`.
|
---|
664 | - `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to
|
---|
665 | https://github.com/guzzle/oauth-subscriber
|
---|
666 |
|
---|
667 | ## Service
|
---|
668 |
|
---|
669 | The service description layer of Guzzle has moved into two separate packages:
|
---|
670 |
|
---|
671 | - https://github.com/guzzle/command Provides a high level abstraction over web
|
---|
672 | services by representing web service operations using commands.
|
---|
673 | - https://github.com/guzzle/guzzle-services Provides an implementation of
|
---|
674 | guzzle/command that provides request serialization and response parsing using
|
---|
675 | Guzzle service descriptions.
|
---|
676 |
|
---|
677 | ## Stream
|
---|
678 |
|
---|
679 | Stream have moved to a separate package available at
|
---|
680 | https://github.com/guzzle/streams.
|
---|
681 |
|
---|
682 | `Guzzle\Stream\StreamInterface` has been given a large update to cleanly take
|
---|
683 | on the responsibilities of `Guzzle\Http\EntityBody` and
|
---|
684 | `Guzzle\Http\EntityBodyInterface` now that they have been removed. The number
|
---|
685 | of methods implemented by the `StreamInterface` has been drastically reduced to
|
---|
686 | allow developers to more easily extend and decorate stream behavior.
|
---|
687 |
|
---|
688 | ## Removed methods from StreamInterface
|
---|
689 |
|
---|
690 | - `getStream` and `setStream` have been removed to better encapsulate streams.
|
---|
691 | - `getMetadata` and `setMetadata` have been removed in favor of
|
---|
692 | `GuzzleHttp\Stream\MetadataStreamInterface`.
|
---|
693 | - `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been
|
---|
694 | removed. This data is accessible when
|
---|
695 | using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`.
|
---|
696 | - `rewind` has been removed. Use `seek(0)` for a similar behavior.
|
---|
697 |
|
---|
698 | ## Renamed methods
|
---|
699 |
|
---|
700 | - `detachStream` has been renamed to `detach`.
|
---|
701 | - `feof` has been renamed to `eof`.
|
---|
702 | - `ftell` has been renamed to `tell`.
|
---|
703 | - `readLine` has moved from an instance method to a static class method of
|
---|
704 | `GuzzleHttp\Stream\Stream`.
|
---|
705 |
|
---|
706 | ## Metadata streams
|
---|
707 |
|
---|
708 | `GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams
|
---|
709 | that contain additional metadata accessible via `getMetadata()`.
|
---|
710 | `GuzzleHttp\Stream\StreamInterface::getMetadata` and
|
---|
711 | `GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed.
|
---|
712 |
|
---|
713 | ## StreamRequestFactory
|
---|
714 |
|
---|
715 | The entire concept of the StreamRequestFactory has been removed. The way this
|
---|
716 | was used in Guzzle 3 broke the actual interface of sending streaming requests
|
---|
717 | (instead of getting back a Response, you got a StreamInterface). Streaming
|
---|
718 | PHP requests are now implemented through the `GuzzleHttp\Adapter\StreamAdapter`.
|
---|
719 |
|
---|
720 | 3.6 to 3.7
|
---|
721 | ----------
|
---|
722 |
|
---|
723 | ### Deprecations
|
---|
724 |
|
---|
725 | - You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.:
|
---|
726 |
|
---|
727 | ```php
|
---|
728 | \Guzzle\Common\Version::$emitWarnings = true;
|
---|
729 | ```
|
---|
730 |
|
---|
731 | The following APIs and options have been marked as deprecated:
|
---|
732 |
|
---|
733 | - Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead.
|
---|
734 | - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
---|
735 | - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
---|
736 | - Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
|
---|
737 | - Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
|
---|
738 | - Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
|
---|
739 | - Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
|
---|
740 | - Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
|
---|
741 | - Marked `Guzzle\Common\Collection::inject()` as deprecated.
|
---|
742 | - Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use
|
---|
743 | `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or
|
---|
744 | `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));`
|
---|
745 |
|
---|
746 | 3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational
|
---|
747 | request methods. When paired with a client's configuration settings, these options allow you to specify default settings
|
---|
748 | for various aspects of a request. Because these options make other previous configuration options redundant, several
|
---|
749 | configuration options and methods of a client and AbstractCommand have been deprecated.
|
---|
750 |
|
---|
751 | - Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`.
|
---|
752 | - Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`.
|
---|
753 | - Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')`
|
---|
754 | - Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0
|
---|
755 |
|
---|
756 | $command = $client->getCommand('foo', array(
|
---|
757 | 'command.headers' => array('Test' => '123'),
|
---|
758 | 'command.response_body' => '/path/to/file'
|
---|
759 | ));
|
---|
760 |
|
---|
761 | // Should be changed to:
|
---|
762 |
|
---|
763 | $command = $client->getCommand('foo', array(
|
---|
764 | 'command.request_options' => array(
|
---|
765 | 'headers' => array('Test' => '123'),
|
---|
766 | 'save_as' => '/path/to/file'
|
---|
767 | )
|
---|
768 | ));
|
---|
769 |
|
---|
770 | ### Interface changes
|
---|
771 |
|
---|
772 | Additions and changes (you will need to update any implementations or subclasses you may have created):
|
---|
773 |
|
---|
774 | - Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
|
---|
775 | createRequest, head, delete, put, patch, post, options, prepareRequest
|
---|
776 | - Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
|
---|
777 | - Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
|
---|
778 | - Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
|
---|
779 | `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
|
---|
780 | resource, string, or EntityBody into the $options parameter to specify the download location of the response.
|
---|
781 | - Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
|
---|
782 | default `array()`
|
---|
783 | - Added `Guzzle\Stream\StreamInterface::isRepeatable`
|
---|
784 | - Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
|
---|
785 |
|
---|
786 | The following methods were removed from interfaces. All of these methods are still available in the concrete classes
|
---|
787 | that implement them, but you should update your code to use alternative methods:
|
---|
788 |
|
---|
789 | - Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
|
---|
790 | `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
|
---|
791 | `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or
|
---|
792 | `$client->setDefaultOption('headers/{header_name}', 'value')`. or
|
---|
793 | `$client->setDefaultOption('headers', array('header_name' => 'value'))`.
|
---|
794 | - Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`.
|
---|
795 | - Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail.
|
---|
796 | - Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail.
|
---|
797 | - Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail.
|
---|
798 | - Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin.
|
---|
799 | - Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin.
|
---|
800 | - Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin.
|
---|
801 |
|
---|
802 | ### Cache plugin breaking changes
|
---|
803 |
|
---|
804 | - CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
|
---|
805 | CacheStorageInterface. These two objects and interface will be removed in a future version.
|
---|
806 | - Always setting X-cache headers on cached responses
|
---|
807 | - Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
|
---|
808 | - `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
|
---|
809 | $request, Response $response);`
|
---|
810 | - `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
|
---|
811 | - `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
|
---|
812 | - Added `CacheStorageInterface::purge($url)`
|
---|
813 | - `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
|
---|
814 | $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
|
---|
815 | CanCacheStrategyInterface $canCache = null)`
|
---|
816 | - Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
|
---|
817 |
|
---|
818 | 3.5 to 3.6
|
---|
819 | ----------
|
---|
820 |
|
---|
821 | * Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
|
---|
822 | * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
|
---|
823 | * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
|
---|
824 | For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader().
|
---|
825 | Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request.
|
---|
826 | * Specific header implementations can be created for complex headers. When a message creates a header, it uses a
|
---|
827 | HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
|
---|
828 | CacheControl header implementation.
|
---|
829 | * Moved getLinks() from Response to just be used on a Link header object.
|
---|
830 |
|
---|
831 | If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
|
---|
832 | HeaderInterface (e.g. toArray(), getAll(), etc.).
|
---|
833 |
|
---|
834 | ### Interface changes
|
---|
835 |
|
---|
836 | * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
|
---|
837 | * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
|
---|
838 | * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
|
---|
839 | Guzzle\Http\Curl\RequestMediator
|
---|
840 | * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
|
---|
841 | * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
|
---|
842 | * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
|
---|
843 |
|
---|
844 | ### Removed deprecated functions
|
---|
845 |
|
---|
846 | * Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
|
---|
847 | * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
|
---|
848 |
|
---|
849 | ### Deprecations
|
---|
850 |
|
---|
851 | * The ability to case-insensitively search for header values
|
---|
852 | * Guzzle\Http\Message\Header::hasExactHeader
|
---|
853 | * Guzzle\Http\Message\Header::raw. Use getAll()
|
---|
854 | * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
|
---|
855 | instead.
|
---|
856 |
|
---|
857 | ### Other changes
|
---|
858 |
|
---|
859 | * All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
---|
860 | * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle
|
---|
861 | directly via interfaces
|
---|
862 | * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
---|
863 | but are a no-op until removed.
|
---|
864 | * Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
|
---|
865 | `Guzzle\Service\Command\ArrayCommandInterface`.
|
---|
866 | * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
|
---|
867 | on a request while the request is still being transferred
|
---|
868 | * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
|
---|
869 |
|
---|
870 | 3.3 to 3.4
|
---|
871 | ----------
|
---|
872 |
|
---|
873 | Base URLs of a client now follow the rules of https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2 when merging URLs.
|
---|
874 |
|
---|
875 | 3.2 to 3.3
|
---|
876 | ----------
|
---|
877 |
|
---|
878 | ### Response::getEtag() quote stripping removed
|
---|
879 |
|
---|
880 | `Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header
|
---|
881 |
|
---|
882 | ### Removed `Guzzle\Http\Utils`
|
---|
883 |
|
---|
884 | The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
|
---|
885 |
|
---|
886 | ### Stream wrapper and type
|
---|
887 |
|
---|
888 | `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase.
|
---|
889 |
|
---|
890 | ### curl.emit_io became emit_io
|
---|
891 |
|
---|
892 | Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the
|
---|
893 | 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
|
---|
894 |
|
---|
895 | 3.1 to 3.2
|
---|
896 | ----------
|
---|
897 |
|
---|
898 | ### CurlMulti is no longer reused globally
|
---|
899 |
|
---|
900 | Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added
|
---|
901 | to a single client can pollute requests dispatched from other clients.
|
---|
902 |
|
---|
903 | If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the
|
---|
904 | ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is
|
---|
905 | created.
|
---|
906 |
|
---|
907 | ```php
|
---|
908 | $multi = new Guzzle\Http\Curl\CurlMulti();
|
---|
909 | $builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json');
|
---|
910 | $builder->addListener('service_builder.create_client', function ($event) use ($multi) {
|
---|
911 | $event['client']->setCurlMulti($multi);
|
---|
912 | }
|
---|
913 | });
|
---|
914 | ```
|
---|
915 |
|
---|
916 | ### No default path
|
---|
917 |
|
---|
918 | URLs no longer have a default path value of '/' if no path was specified.
|
---|
919 |
|
---|
920 | Before:
|
---|
921 |
|
---|
922 | ```php
|
---|
923 | $request = $client->get('http://www.foo.com');
|
---|
924 | echo $request->getUrl();
|
---|
925 | // >> http://www.foo.com/
|
---|
926 | ```
|
---|
927 |
|
---|
928 | After:
|
---|
929 |
|
---|
930 | ```php
|
---|
931 | $request = $client->get('http://www.foo.com');
|
---|
932 | echo $request->getUrl();
|
---|
933 | // >> http://www.foo.com
|
---|
934 | ```
|
---|
935 |
|
---|
936 | ### Less verbose BadResponseException
|
---|
937 |
|
---|
938 | The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and
|
---|
939 | response information. You can, however, get access to the request and response object by calling `getRequest()` or
|
---|
940 | `getResponse()` on the exception object.
|
---|
941 |
|
---|
942 | ### Query parameter aggregation
|
---|
943 |
|
---|
944 | Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a
|
---|
945 | setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is
|
---|
946 | responsible for handling the aggregation of multi-valued query string variables into a flattened hash.
|
---|
947 |
|
---|
948 | 2.8 to 3.x
|
---|
949 | ----------
|
---|
950 |
|
---|
951 | ### Guzzle\Service\Inspector
|
---|
952 |
|
---|
953 | Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig`
|
---|
954 |
|
---|
955 | **Before**
|
---|
956 |
|
---|
957 | ```php
|
---|
958 | use Guzzle\Service\Inspector;
|
---|
959 |
|
---|
960 | class YourClient extends \Guzzle\Service\Client
|
---|
961 | {
|
---|
962 | public static function factory($config = array())
|
---|
963 | {
|
---|
964 | $default = array();
|
---|
965 | $required = array('base_url', 'username', 'api_key');
|
---|
966 | $config = Inspector::fromConfig($config, $default, $required);
|
---|
967 |
|
---|
968 | $client = new self(
|
---|
969 | $config->get('base_url'),
|
---|
970 | $config->get('username'),
|
---|
971 | $config->get('api_key')
|
---|
972 | );
|
---|
973 | $client->setConfig($config);
|
---|
974 |
|
---|
975 | $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
|
---|
976 |
|
---|
977 | return $client;
|
---|
978 | }
|
---|
979 | ```
|
---|
980 |
|
---|
981 | **After**
|
---|
982 |
|
---|
983 | ```php
|
---|
984 | use Guzzle\Common\Collection;
|
---|
985 |
|
---|
986 | class YourClient extends \Guzzle\Service\Client
|
---|
987 | {
|
---|
988 | public static function factory($config = array())
|
---|
989 | {
|
---|
990 | $default = array();
|
---|
991 | $required = array('base_url', 'username', 'api_key');
|
---|
992 | $config = Collection::fromConfig($config, $default, $required);
|
---|
993 |
|
---|
994 | $client = new self(
|
---|
995 | $config->get('base_url'),
|
---|
996 | $config->get('username'),
|
---|
997 | $config->get('api_key')
|
---|
998 | );
|
---|
999 | $client->setConfig($config);
|
---|
1000 |
|
---|
1001 | $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
|
---|
1002 |
|
---|
1003 | return $client;
|
---|
1004 | }
|
---|
1005 | ```
|
---|
1006 |
|
---|
1007 | ### Convert XML Service Descriptions to JSON
|
---|
1008 |
|
---|
1009 | **Before**
|
---|
1010 |
|
---|
1011 | ```xml
|
---|
1012 | <?xml version="1.0" encoding="UTF-8"?>
|
---|
1013 | <client>
|
---|
1014 | <commands>
|
---|
1015 | <!-- Groups -->
|
---|
1016 | <command name="list_groups" method="GET" uri="groups.json">
|
---|
1017 | <doc>Get a list of groups</doc>
|
---|
1018 | </command>
|
---|
1019 | <command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'>
|
---|
1020 | <doc>Uses a search query to get a list of groups</doc>
|
---|
1021 | <param name="query" type="string" required="true" />
|
---|
1022 | </command>
|
---|
1023 | <command name="create_group" method="POST" uri="groups.json">
|
---|
1024 | <doc>Create a group</doc>
|
---|
1025 | <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
|
---|
1026 | <param name="Content-Type" location="header" static="application/json"/>
|
---|
1027 | </command>
|
---|
1028 | <command name="delete_group" method="DELETE" uri="groups/{{id}}.json">
|
---|
1029 | <doc>Delete a group by ID</doc>
|
---|
1030 | <param name="id" type="integer" required="true"/>
|
---|
1031 | </command>
|
---|
1032 | <command name="get_group" method="GET" uri="groups/{{id}}.json">
|
---|
1033 | <param name="id" type="integer" required="true"/>
|
---|
1034 | </command>
|
---|
1035 | <command name="update_group" method="PUT" uri="groups/{{id}}.json">
|
---|
1036 | <doc>Update a group</doc>
|
---|
1037 | <param name="id" type="integer" required="true"/>
|
---|
1038 | <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
|
---|
1039 | <param name="Content-Type" location="header" static="application/json"/>
|
---|
1040 | </command>
|
---|
1041 | </commands>
|
---|
1042 | </client>
|
---|
1043 | ```
|
---|
1044 |
|
---|
1045 | **After**
|
---|
1046 |
|
---|
1047 | ```json
|
---|
1048 | {
|
---|
1049 | "name": "Zendesk REST API v2",
|
---|
1050 | "apiVersion": "2012-12-31",
|
---|
1051 | "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users",
|
---|
1052 | "operations": {
|
---|
1053 | "list_groups": {
|
---|
1054 | "httpMethod":"GET",
|
---|
1055 | "uri": "groups.json",
|
---|
1056 | "summary": "Get a list of groups"
|
---|
1057 | },
|
---|
1058 | "search_groups":{
|
---|
1059 | "httpMethod":"GET",
|
---|
1060 | "uri": "search.json?query=\"{query} type:group\"",
|
---|
1061 | "summary": "Uses a search query to get a list of groups",
|
---|
1062 | "parameters":{
|
---|
1063 | "query":{
|
---|
1064 | "location": "uri",
|
---|
1065 | "description":"Zendesk Search Query",
|
---|
1066 | "type": "string",
|
---|
1067 | "required": true
|
---|
1068 | }
|
---|
1069 | }
|
---|
1070 | },
|
---|
1071 | "create_group": {
|
---|
1072 | "httpMethod":"POST",
|
---|
1073 | "uri": "groups.json",
|
---|
1074 | "summary": "Create a group",
|
---|
1075 | "parameters":{
|
---|
1076 | "data": {
|
---|
1077 | "type": "array",
|
---|
1078 | "location": "body",
|
---|
1079 | "description":"Group JSON",
|
---|
1080 | "filters": "json_encode",
|
---|
1081 | "required": true
|
---|
1082 | },
|
---|
1083 | "Content-Type":{
|
---|
1084 | "type": "string",
|
---|
1085 | "location":"header",
|
---|
1086 | "static": "application/json"
|
---|
1087 | }
|
---|
1088 | }
|
---|
1089 | },
|
---|
1090 | "delete_group": {
|
---|
1091 | "httpMethod":"DELETE",
|
---|
1092 | "uri": "groups/{id}.json",
|
---|
1093 | "summary": "Delete a group",
|
---|
1094 | "parameters":{
|
---|
1095 | "id":{
|
---|
1096 | "location": "uri",
|
---|
1097 | "description":"Group to delete by ID",
|
---|
1098 | "type": "integer",
|
---|
1099 | "required": true
|
---|
1100 | }
|
---|
1101 | }
|
---|
1102 | },
|
---|
1103 | "get_group": {
|
---|
1104 | "httpMethod":"GET",
|
---|
1105 | "uri": "groups/{id}.json",
|
---|
1106 | "summary": "Get a ticket",
|
---|
1107 | "parameters":{
|
---|
1108 | "id":{
|
---|
1109 | "location": "uri",
|
---|
1110 | "description":"Group to get by ID",
|
---|
1111 | "type": "integer",
|
---|
1112 | "required": true
|
---|
1113 | }
|
---|
1114 | }
|
---|
1115 | },
|
---|
1116 | "update_group": {
|
---|
1117 | "httpMethod":"PUT",
|
---|
1118 | "uri": "groups/{id}.json",
|
---|
1119 | "summary": "Update a group",
|
---|
1120 | "parameters":{
|
---|
1121 | "id": {
|
---|
1122 | "location": "uri",
|
---|
1123 | "description":"Group to update by ID",
|
---|
1124 | "type": "integer",
|
---|
1125 | "required": true
|
---|
1126 | },
|
---|
1127 | "data": {
|
---|
1128 | "type": "array",
|
---|
1129 | "location": "body",
|
---|
1130 | "description":"Group JSON",
|
---|
1131 | "filters": "json_encode",
|
---|
1132 | "required": true
|
---|
1133 | },
|
---|
1134 | "Content-Type":{
|
---|
1135 | "type": "string",
|
---|
1136 | "location":"header",
|
---|
1137 | "static": "application/json"
|
---|
1138 | }
|
---|
1139 | }
|
---|
1140 | }
|
---|
1141 | }
|
---|
1142 | ```
|
---|
1143 |
|
---|
1144 | ### Guzzle\Service\Description\ServiceDescription
|
---|
1145 |
|
---|
1146 | Commands are now called Operations
|
---|
1147 |
|
---|
1148 | **Before**
|
---|
1149 |
|
---|
1150 | ```php
|
---|
1151 | use Guzzle\Service\Description\ServiceDescription;
|
---|
1152 |
|
---|
1153 | $sd = new ServiceDescription();
|
---|
1154 | $sd->getCommands(); // @returns ApiCommandInterface[]
|
---|
1155 | $sd->hasCommand($name);
|
---|
1156 | $sd->getCommand($name); // @returns ApiCommandInterface|null
|
---|
1157 | $sd->addCommand($command); // @param ApiCommandInterface $command
|
---|
1158 | ```
|
---|
1159 |
|
---|
1160 | **After**
|
---|
1161 |
|
---|
1162 | ```php
|
---|
1163 | use Guzzle\Service\Description\ServiceDescription;
|
---|
1164 |
|
---|
1165 | $sd = new ServiceDescription();
|
---|
1166 | $sd->getOperations(); // @returns OperationInterface[]
|
---|
1167 | $sd->hasOperation($name);
|
---|
1168 | $sd->getOperation($name); // @returns OperationInterface|null
|
---|
1169 | $sd->addOperation($operation); // @param OperationInterface $operation
|
---|
1170 | ```
|
---|
1171 |
|
---|
1172 | ### Guzzle\Common\Inflection\Inflector
|
---|
1173 |
|
---|
1174 | Namespace is now `Guzzle\Inflection\Inflector`
|
---|
1175 |
|
---|
1176 | ### Guzzle\Http\Plugin
|
---|
1177 |
|
---|
1178 | Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below.
|
---|
1179 |
|
---|
1180 | ### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log
|
---|
1181 |
|
---|
1182 | Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively.
|
---|
1183 |
|
---|
1184 | **Before**
|
---|
1185 |
|
---|
1186 | ```php
|
---|
1187 | use Guzzle\Common\Log\ClosureLogAdapter;
|
---|
1188 | use Guzzle\Http\Plugin\LogPlugin;
|
---|
1189 |
|
---|
1190 | /** @var \Guzzle\Http\Client */
|
---|
1191 | $client;
|
---|
1192 |
|
---|
1193 | // $verbosity is an integer indicating desired message verbosity level
|
---|
1194 | $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE);
|
---|
1195 | ```
|
---|
1196 |
|
---|
1197 | **After**
|
---|
1198 |
|
---|
1199 | ```php
|
---|
1200 | use Guzzle\Log\ClosureLogAdapter;
|
---|
1201 | use Guzzle\Log\MessageFormatter;
|
---|
1202 | use Guzzle\Plugin\Log\LogPlugin;
|
---|
1203 |
|
---|
1204 | /** @var \Guzzle\Http\Client */
|
---|
1205 | $client;
|
---|
1206 |
|
---|
1207 | // $format is a string indicating desired message format -- @see MessageFormatter
|
---|
1208 | $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT);
|
---|
1209 | ```
|
---|
1210 |
|
---|
1211 | ### Guzzle\Http\Plugin\CurlAuthPlugin
|
---|
1212 |
|
---|
1213 | Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`.
|
---|
1214 |
|
---|
1215 | ### Guzzle\Http\Plugin\ExponentialBackoffPlugin
|
---|
1216 |
|
---|
1217 | Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes.
|
---|
1218 |
|
---|
1219 | **Before**
|
---|
1220 |
|
---|
1221 | ```php
|
---|
1222 | use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
|
---|
1223 |
|
---|
1224 | $backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge(
|
---|
1225 | ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429)
|
---|
1226 | ));
|
---|
1227 |
|
---|
1228 | $client->addSubscriber($backoffPlugin);
|
---|
1229 | ```
|
---|
1230 |
|
---|
1231 | **After**
|
---|
1232 |
|
---|
1233 | ```php
|
---|
1234 | use Guzzle\Plugin\Backoff\BackoffPlugin;
|
---|
1235 | use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
|
---|
1236 |
|
---|
1237 | // Use convenient factory method instead -- see implementation for ideas of what
|
---|
1238 | // you can do with chaining backoff strategies
|
---|
1239 | $backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge(
|
---|
1240 | HttpBackoffStrategy::getDefaultFailureCodes(), array(429)
|
---|
1241 | ));
|
---|
1242 | $client->addSubscriber($backoffPlugin);
|
---|
1243 | ```
|
---|
1244 |
|
---|
1245 | ### Known Issues
|
---|
1246 |
|
---|
1247 | #### [BUG] Accept-Encoding header behavior changed unintentionally.
|
---|
1248 |
|
---|
1249 | (See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e)
|
---|
1250 |
|
---|
1251 | In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to
|
---|
1252 | properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen.
|
---|
1253 | See issue #217 for a workaround, or use a version containing the fix.
|
---|