scratch – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
87 | office | 1 | Guzzle Upgrade Guide |
2 | ==================== |
||
3 | |||
4 | 3.x to 4.0 |
||
5 | ---------- |
||
6 | |||
7 | ## Overarching changes: |
||
8 | |||
9 | - Now requires PHP 5.4 or greater. |
||
10 | - No longer requires cURL to send requests. |
||
11 | - Guzzle no longer wraps every exception it throws. Only exceptions that are |
||
12 | recoverable are now wrapped by Guzzle. |
||
13 | - Various namespaces have been removed or renamed. |
||
14 | - No longer requiring the Symfony EventDispatcher. A custom event dispatcher |
||
15 | based on the Symfony EventDispatcher is |
||
16 | now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant |
||
17 | speed and functionality improvements). |
||
18 | |||
19 | Changes per Guzzle 3.x namespace are described below. |
||
20 | |||
21 | ## Batch |
||
22 | |||
23 | The `Guzzle\Batch` namespace has been removed. This is best left to |
||
24 | third-parties to implement on top of Guzzle's core HTTP library. |
||
25 | |||
26 | ## Cache |
||
27 | |||
28 | The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement |
||
29 | has been implemented yet, but hoping to utilize a PSR cache interface). |
||
30 | |||
31 | ## Common |
||
32 | |||
33 | - Removed all of the wrapped exceptions. It's better to use the standard PHP |
||
34 | library for unrecoverable exceptions. |
||
35 | - `FromConfigInterface` has been removed. |
||
36 | - `Guzzle\Common\Version` has been removed. The VERSION constant can be found |
||
37 | at `GuzzleHttp\ClientInterface::VERSION`. |
||
38 | |||
39 | ### Collection |
||
40 | |||
41 | - `getAll` has been removed. Use `toArray` to convert a collection to an array. |
||
42 | - `inject` has been removed. |
||
43 | - `keySearch` has been removed. |
||
44 | - `getPath` no longer supports wildcard expressions. Use something better like |
||
45 | JMESPath for this. |
||
46 | - `setPath` now supports appending to an existing array via the `[]` notation. |
||
47 | |||
48 | ### Events |
||
49 | |||
50 | Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses |
||
51 | `GuzzleHttp\Event\Emitter`. |
||
52 | |||
53 | - `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by |
||
54 | `GuzzleHttp\Event\EmitterInterface`. |
||
55 | - `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by |
||
56 | `GuzzleHttp\Event\Emitter`. |
||
57 | - `Symfony\Component\EventDispatcher\Event` is replaced by |
||
58 | `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in |
||
59 | `GuzzleHttp\Event\EventInterface`. |
||
60 | - `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and |
||
61 | `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the |
||
62 | event emitter of a request, client, etc. now uses the `getEmitter` method |
||
63 | rather than the `getDispatcher` method. |
||
64 | |||
65 | #### Emitter |
||
66 | |||
67 | - Use the `once()` method to add a listener that automatically removes itself |
||
68 | the first time it is invoked. |
||
69 | - Use the `listeners()` method to retrieve a list of event listeners rather than |
||
70 | the `getListeners()` method. |
||
71 | - Use `emit()` instead of `dispatch()` to emit an event from an emitter. |
||
72 | - Use `attach()` instead of `addSubscriber()` and `detach()` instead of |
||
73 | `removeSubscriber()`. |
||
74 | |||
75 | ```php |
||
76 | $mock = new Mock(); |
||
77 | // 3.x |
||
78 | $request->getEventDispatcher()->addSubscriber($mock); |
||
79 | $request->getEventDispatcher()->removeSubscriber($mock); |
||
80 | // 4.x |
||
81 | $request->getEmitter()->attach($mock); |
||
82 | $request->getEmitter()->detach($mock); |
||
83 | ``` |
||
84 | |||
85 | Use the `on()` method to add a listener rather than the `addListener()` method. |
||
86 | |||
87 | ```php |
||
88 | // 3.x |
||
89 | $request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } ); |
||
90 | // 4.x |
||
91 | $request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } ); |
||
92 | ``` |
||
93 | |||
94 | ## Http |
||
95 | |||
96 | ### General changes |
||
97 | |||
98 | - The cacert.pem certificate has been moved to `src/cacert.pem`. |
||
99 | - Added the concept of adapters that are used to transfer requests over the |
||
100 | wire. |
||
101 | - Simplified the event system. |
||
102 | - Sending requests in parallel is still possible, but batching is no longer a |
||
103 | concept of the HTTP layer. Instead, you must use the `complete` and `error` |
||
104 | events to asynchronously manage parallel request transfers. |
||
105 | - `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`. |
||
106 | - `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`. |
||
107 | - QueryAggregators have been rewritten so that they are simply callable |
||
108 | functions. |
||
109 | - `GuzzleHttp\StaticClient` has been removed. Use the functions provided in |
||
110 | `functions.php` for an easy to use static client instance. |
||
111 | - Exceptions in `GuzzleHttp\Exception` have been updated to all extend from |
||
112 | `GuzzleHttp\Exception\TransferException`. |
||
113 | |||
114 | ### Client |
||
115 | |||
116 | Calling methods like `get()`, `post()`, `head()`, etc. no longer create and |
||
117 | return a request, but rather creates a request, sends the request, and returns |
||
118 | the response. |
||
119 | |||
120 | ```php |
||
121 | // 3.0 |
||
122 | $request = $client->get('/'); |
||
123 | $response = $request->send(); |
||
124 | |||
125 | // 4.0 |
||
126 | $response = $client->get('/'); |
||
127 | |||
128 | // or, to mirror the previous behavior |
||
129 | $request = $client->createRequest('GET', '/'); |
||
130 | $response = $client->send($request); |
||
131 | ``` |
||
132 | |||
133 | `GuzzleHttp\ClientInterface` has changed. |
||
134 | |||
135 | - The `send` method no longer accepts more than one request. Use `sendAll` to |
||
136 | send multiple requests in parallel. |
||
137 | - `setUserAgent()` has been removed. Use a default request option instead. You |
||
138 | could, for example, do something like: |
||
139 | `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`. |
||
140 | - `setSslVerification()` has been removed. Use default request options instead, |
||
141 | like `$client->setConfig('defaults/verify', true)`. |
||
142 | |||
143 | `GuzzleHttp\Client` has changed. |
||
144 | |||
145 | - The constructor now accepts only an associative array. You can include a |
||
146 | `base_url` string or array to use a URI template as the base URL of a client. |
||
147 | You can also specify a `defaults` key that is an associative array of default |
||
148 | request options. You can pass an `adapter` to use a custom adapter, |
||
149 | `batch_adapter` to use a custom adapter for sending requests in parallel, or |
||
150 | a `message_factory` to change the factory used to create HTTP requests and |
||
151 | responses. |
||
152 | - The client no longer emits a `client.create_request` event. |
||
153 | - Creating requests with a client no longer automatically utilize a URI |
||
154 | template. You must pass an array into a creational method (e.g., |
||
155 | `createRequest`, `get`, `put`, etc.) in order to expand a URI template. |
||
156 | |||
157 | ### Messages |
||
158 | |||
159 | Messages no longer have references to their counterparts (i.e., a request no |
||
160 | longer has a reference to it's response, and a response no loger has a |
||
161 | reference to its request). This association is now managed through a |
||
162 | `GuzzleHttp\Adapter\TransactionInterface` object. You can get references to |
||
163 | these transaction objects using request events that are emitted over the |
||
164 | lifecycle of a request. |
||
165 | |||
166 | #### Requests with a body |
||
167 | |||
168 | - `GuzzleHttp\Message\EntityEnclosingRequest` and |
||
169 | `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The |
||
170 | separation between requests that contain a body and requests that do not |
||
171 | contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface` |
||
172 | handles both use cases. |
||
173 | - Any method that previously accepts a `GuzzleHttp\Response` object now accept a |
||
174 | `GuzzleHttp\Message\ResponseInterface`. |
||
175 | - `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to |
||
176 | `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create |
||
177 | both requests and responses and is implemented in |
||
178 | `GuzzleHttp\Message\MessageFactory`. |
||
179 | - POST field and file methods have been removed from the request object. You |
||
180 | must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface` |
||
181 | to control the format of a POST body. Requests that are created using a |
||
182 | standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use |
||
183 | a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if |
||
184 | the method is POST and no body is provided. |
||
185 | |||
186 | ```php |
||
187 | $request = $client->createRequest('POST', '/'); |
||
188 | $request->getBody()->setField('foo', 'bar'); |
||
189 | $request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r'))); |
||
190 | ``` |
||
191 | |||
192 | #### Headers |
||
193 | |||
194 | - `GuzzleHttp\Message\Header` has been removed. Header values are now simply |
||
195 | represented by an array of values or as a string. Header values are returned |
||
196 | as a string by default when retrieving a header value from a message. You can |
||
197 | pass an optional argument of `true` to retrieve a header value as an array |
||
198 | of strings instead of a single concatenated string. |
||
199 | - `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to |
||
200 | `GuzzleHttp\Post`. This interface has been simplified and now allows the |
||
201 | addition of arbitrary headers. |
||
202 | - Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most |
||
203 | of the custom headers are now handled separately in specific |
||
204 | subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has |
||
205 | been updated to properly handle headers that contain parameters (like the |
||
206 | `Link` header). |
||
207 | |||
208 | #### Responses |
||
209 | |||
210 | - `GuzzleHttp\Message\Response::getInfo()` and |
||
211 | `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event |
||
212 | system to retrieve this type of information. |
||
213 | - `GuzzleHttp\Message\Response::getRawHeaders()` has been removed. |
||
214 | - `GuzzleHttp\Message\Response::getMessage()` has been removed. |
||
215 | - `GuzzleHttp\Message\Response::calculateAge()` and other cache specific |
||
216 | methods have moved to the CacheSubscriber. |
||
217 | - Header specific helper functions like `getContentMd5()` have been removed. |
||
218 | Just use `getHeader('Content-MD5')` instead. |
||
219 | - `GuzzleHttp\Message\Response::setRequest()` and |
||
220 | `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event |
||
221 | system to work with request and response objects as a transaction. |
||
222 | - `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the |
||
223 | Redirect subscriber instead. |
||
224 | - `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have |
||
225 | been removed. Use `getStatusCode()` instead. |
||
226 | |||
227 | #### Streaming responses |
||
228 | |||
229 | Streaming requests can now be created by a client directly, returning a |
||
230 | `GuzzleHttp\Message\ResponseInterface` object that contains a body stream |
||
231 | referencing an open PHP HTTP stream. |
||
232 | |||
233 | ```php |
||
234 | // 3.0 |
||
235 | use Guzzle\Stream\PhpStreamRequestFactory; |
||
236 | $request = $client->get('/'); |
||
237 | $factory = new PhpStreamRequestFactory(); |
||
238 | $stream = $factory->fromRequest($request); |
||
239 | $data = $stream->read(1024); |
||
240 | |||
241 | // 4.0 |
||
242 | $response = $client->get('/', ['stream' => true]); |
||
243 | // Read some data off of the stream in the response body |
||
244 | $data = $response->getBody()->read(1024); |
||
245 | ``` |
||
246 | |||
247 | #### Redirects |
||
248 | |||
249 | The `configureRedirects()` method has been removed in favor of a |
||
250 | `allow_redirects` request option. |
||
251 | |||
252 | ```php |
||
253 | // Standard redirects with a default of a max of 5 redirects |
||
254 | $request = $client->createRequest('GET', '/', ['allow_redirects' => true]); |
||
255 | |||
256 | // Strict redirects with a custom number of redirects |
||
257 | $request = $client->createRequest('GET', '/', [ |
||
258 | 'allow_redirects' => ['max' => 5, 'strict' => true] |
||
259 | ]); |
||
260 | ``` |
||
261 | |||
262 | #### EntityBody |
||
263 | |||
264 | EntityBody interfaces and classes have been removed or moved to |
||
265 | `GuzzleHttp\Stream`. All classes and interfaces that once required |
||
266 | `GuzzleHttp\EntityBodyInterface` now require |
||
267 | `GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no |
||
268 | longer uses `GuzzleHttp\EntityBody::factory` but now uses |
||
269 | `GuzzleHttp\Stream\Stream::factory` or even better: |
||
270 | `GuzzleHttp\Stream\create()`. |
||
271 | |||
272 | - `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface` |
||
273 | - `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream` |
||
274 | - `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream` |
||
275 | - `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream` |
||
276 | - `Guzzle\Http\IoEmittyinEntityBody` has been removed. |
||
277 | |||
278 | #### Request lifecycle events |
||
279 | |||
280 | Requests previously submitted a large number of requests. The number of events |
||
281 | emitted over the lifecycle of a request has been significantly reduced to make |
||
282 | it easier to understand how to extend the behavior of a request. All events |
||
283 | emitted during the lifecycle of a request now emit a custom |
||
284 | `GuzzleHttp\Event\EventInterface` object that contains context providing |
||
285 | methods and a way in which to modify the transaction at that specific point in |
||
286 | time (e.g., intercept the request and set a response on the transaction). |
||
287 | |||
288 | - `request.before_send` has been renamed to ``before`` and now emits a |
||
289 | `GuzzleHttp\Event\BeforeEvent` |
||
290 | - `request.complete` has been renamed to `complete` and now emits a |
||
291 | `GuzzleHttp\Event\CompleteEvent`. |
||
292 | - `request.sent` has been removed. Use `complete`. |
||
293 | - `request.success` has been removed. Use `complete`. |
||
294 | - `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`. |
||
295 | - `request.exception` has been removed. Use `error`. |
||
296 | - `request.receive.status_line` has been removed. |
||
297 | - `curl.callback.progress` has been removed. Use a custom `StreamInterface` to |
||
298 | maintain a status update. |
||
299 | - `curl.callback.write` has been removed. Use a custom `StreamInterface` to |
||
300 | intercept writes. |
||
301 | - `curl.callback.read` has been removed. Use a custom `StreamInterface` to |
||
302 | intercept reads. |
||
303 | |||
304 | `headers` is a new event that is emitted after the response headers of a |
||
305 | request have been received before the body of the response is downloaded. This |
||
306 | event emits a `GuzzleHttp\Event\HeadersEvent`. |
||
307 | |||
308 | You can intercept a request and inject a response using the `intercept()` event |
||
309 | of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and |
||
310 | `GuzzleHttp\Event\ErrorEvent` event. |
||
311 | |||
312 | See: http://docs.guzzlephp.org/en/latest/events.html |
||
313 | |||
314 | ## Inflection |
||
315 | |||
316 | The `Guzzle\Inflection` namespace has been removed. This is not a core concern |
||
317 | of Guzzle. |
||
318 | |||
319 | ## Iterator |
||
320 | |||
321 | The `Guzzle\Iterator` namespace has been removed. |
||
322 | |||
323 | - `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and |
||
324 | `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of |
||
325 | Guzzle itself. |
||
326 | - `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent |
||
327 | class is shipped with PHP 5.4. |
||
328 | - `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because |
||
329 | it's easier to just wrap an iterator in a generator that maps values. |
||
330 | |||
331 | For a replacement of these iterators, see https://github.com/nikic/iter |
||
332 | |||
333 | ## Log |
||
334 | |||
335 | The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The |
||
336 | `Guzzle\Log` namespace has been removed. Guzzle now relies on |
||
337 | `Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been |
||
338 | moved to `GuzzleHttp\Subscriber\Log\Formatter`. |
||
339 | |||
340 | ## Parser |
||
341 | |||
342 | The `Guzzle\Parser` namespace has been removed. This was previously used to |
||
343 | make it possible to plug in custom parsers for cookies, messages, URI |
||
344 | templates, and URLs; however, this level of complexity is not needed in Guzzle |
||
345 | so it has been removed. |
||
346 | |||
347 | - Cookie: Cookie parsing logic has been moved to |
||
348 | `GuzzleHttp\Cookie\SetCookie::fromString`. |
||
349 | - Message: Message parsing logic for both requests and responses has been moved |
||
350 | to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only |
||
351 | used in debugging or deserializing messages, so it doesn't make sense for |
||
352 | Guzzle as a library to add this level of complexity to parsing messages. |
||
353 | - UriTemplate: URI template parsing has been moved to |
||
354 | `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL |
||
355 | URI template library if it is installed. |
||
356 | - Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously |
||
357 | it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary, |
||
358 | then developers are free to subclass `GuzzleHttp\Url`. |
||
359 | |||
360 | ## Plugin |
||
361 | |||
362 | The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`. |
||
363 | Several plugins are shipping with the core Guzzle library under this namespace. |
||
364 | |||
365 | - `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar |
||
366 | code has moved to `GuzzleHttp\Cookie`. |
||
367 | - `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin. |
||
368 | - `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is |
||
369 | received. |
||
370 | - `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin. |
||
371 | - `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before |
||
372 | sending. This subscriber is attached to all requests by default. |
||
373 | - `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin. |
||
374 | |||
375 | The following plugins have been removed (third-parties are free to re-implement |
||
376 | these if needed): |
||
377 | |||
378 | - `GuzzleHttp\Plugin\Async` has been removed. |
||
379 | - `GuzzleHttp\Plugin\CurlAuth` has been removed. |
||
380 | - `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This |
||
381 | functionality should instead be implemented with event listeners that occur |
||
382 | after normal response parsing occurs in the guzzle/command package. |
||
383 | |||
384 | The following plugins are not part of the core Guzzle package, but are provided |
||
385 | in separate repositories: |
||
386 | |||
387 | - `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be muchs simpler |
||
388 | to build custom retry policies using simple functions rather than various |
||
389 | chained classes. See: https://github.com/guzzle/retry-subscriber |
||
390 | - `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to |
||
391 | https://github.com/guzzle/cache-subscriber |
||
392 | - `Guzzle\Http\Plugin\Log\LogPlugin` has moved to |
||
393 | https://github.com/guzzle/log-subscriber |
||
394 | - `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to |
||
395 | https://github.com/guzzle/message-integrity-subscriber |
||
396 | - `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to |
||
397 | `GuzzleHttp\Subscriber\MockSubscriber`. |
||
398 | - `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to |
||
399 | https://github.com/guzzle/oauth-subscriber |
||
400 | |||
401 | ## Service |
||
402 | |||
403 | The service description layer of Guzzle has moved into two separate packages: |
||
404 | |||
405 | - http://github.com/guzzle/command Provides a high level abstraction over web |
||
406 | services by representing web service operations using commands. |
||
407 | - http://github.com/guzzle/guzzle-services Provides an implementation of |
||
408 | guzzle/command that provides request serialization and response parsing using |
||
409 | Guzzle service descriptions. |
||
410 | |||
411 | ## Stream |
||
412 | |||
413 | Stream have moved to a separate package available at |
||
414 | https://github.com/guzzle/streams. |
||
415 | |||
416 | `Guzzle\Stream\StreamInterface` has been given a large update to cleanly take |
||
417 | on the responsibilities of `Guzzle\Http\EntityBody` and |
||
418 | `Guzzle\Http\EntityBodyInterface` now that they have been removed. The number |
||
419 | of methods implemented by the `StreamInterface` has been drastically reduced to |
||
420 | allow developers to more easily extend and decorate stream behavior. |
||
421 | |||
422 | ## Removed methods from StreamInterface |
||
423 | |||
424 | - `getStream` and `setStream` have been removed to better encapsulate streams. |
||
425 | - `getMetadata` and `setMetadata` have been removed in favor of |
||
426 | `GuzzleHttp\Stream\MetadataStreamInterface`. |
||
427 | - `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been |
||
428 | removed. This data is accessible when |
||
429 | using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`. |
||
430 | - `rewind` has been removed. Use `seek(0)` for a similar behavior. |
||
431 | |||
432 | ## Renamed methods |
||
433 | |||
434 | - `detachStream` has been renamed to `detach`. |
||
435 | - `feof` has been renamed to `eof`. |
||
436 | - `ftell` has been renamed to `tell`. |
||
437 | - `readLine` has moved from an instance method to a static class method of |
||
438 | `GuzzleHttp\Stream\Stream`. |
||
439 | |||
440 | ## Metadata streams |
||
441 | |||
442 | `GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams |
||
443 | that contain additonal metadata accessible via `getMetadata()`. |
||
444 | `GuzzleHttp\Stream\StreamInterface::getMetadata` and |
||
445 | `GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed. |
||
446 | |||
447 | ## StreamRequestFactory |
||
448 | |||
449 | The entire concept of the StreamRequestFactory has been removed. The way this |
||
450 | was used in Guzzle 3 broke the actual interface of sending streaming requests |
||
451 | (instead of getting back a Response, you got a StreamInterface). Streeaming |
||
452 | PHP requests are now implemented throught the `GuzzleHttp\Adapter\StreamAdapter`. |
||
453 | |||
454 | 3.6 to 3.7 |
||
455 | ---------- |
||
456 | |||
457 | ### Deprecations |
||
458 | |||
459 | - You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.: |
||
460 | |||
461 | ```php |
||
462 | \Guzzle\Common\Version::$emitWarnings = true; |
||
463 | ``` |
||
464 | |||
465 | The following APIs and options have been marked as deprecated: |
||
466 | |||
467 | - Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead. |
||
468 | - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. |
||
469 | - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. |
||
470 | - Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. |
||
471 | - Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. |
||
472 | - Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated |
||
473 | - Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. |
||
474 | - Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. |
||
475 | - Marked `Guzzle\Common\Collection::inject()` as deprecated. |
||
476 | - Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use |
||
477 | `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or |
||
478 | `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` |
||
479 | |||
480 | 3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational |
||
481 | request methods. When paired with a client's configuration settings, these options allow you to specify default settings |
||
482 | for various aspects of a request. Because these options make other previous configuration options redundant, several |
||
483 | configuration options and methods of a client and AbstractCommand have been deprecated. |
||
484 | |||
485 | - Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`. |
||
486 | - Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`. |
||
487 | - Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')` |
||
488 | - Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0 |
||
489 | |||
490 | $command = $client->getCommand('foo', array( |
||
491 | 'command.headers' => array('Test' => '123'), |
||
492 | 'command.response_body' => '/path/to/file' |
||
493 | )); |
||
494 | |||
495 | // Should be changed to: |
||
496 | |||
497 | $command = $client->getCommand('foo', array( |
||
498 | 'command.request_options' => array( |
||
499 | 'headers' => array('Test' => '123'), |
||
500 | 'save_as' => '/path/to/file' |
||
501 | ) |
||
502 | )); |
||
503 | |||
504 | ### Interface changes |
||
505 | |||
506 | Additions and changes (you will need to update any implementations or subclasses you may have created): |
||
507 | |||
508 | - Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: |
||
509 | createRequest, head, delete, put, patch, post, options, prepareRequest |
||
510 | - Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` |
||
511 | - Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` |
||
512 | - Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to |
||
513 | `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a |
||
514 | resource, string, or EntityBody into the $options parameter to specify the download location of the response. |
||
515 | - Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a |
||
516 | default `array()` |
||
517 | - Added `Guzzle\Stream\StreamInterface::isRepeatable` |
||
518 | - Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. |
||
519 | |||
520 | The following methods were removed from interfaces. All of these methods are still available in the concrete classes |
||
521 | that implement them, but you should update your code to use alternative methods: |
||
522 | |||
523 | - Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use |
||
524 | `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or |
||
525 | `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or |
||
526 | `$client->setDefaultOption('headers/{header_name}', 'value')`. or |
||
527 | `$client->setDefaultOption('headers', array('header_name' => 'value'))`. |
||
528 | - Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`. |
||
529 | - Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail. |
||
530 | - Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail. |
||
531 | - Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail. |
||
532 | - Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin. |
||
533 | - Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin. |
||
534 | - Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin. |
||
535 | |||
536 | ### Cache plugin breaking changes |
||
537 | |||
538 | - CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a |
||
539 | CacheStorageInterface. These two objects and interface will be removed in a future version. |
||
540 | - Always setting X-cache headers on cached responses |
||
541 | - Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin |
||
542 | - `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface |
||
543 | $request, Response $response);` |
||
544 | - `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` |
||
545 | - `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` |
||
546 | - Added `CacheStorageInterface::purge($url)` |
||
547 | - `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin |
||
548 | $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, |
||
549 | CanCacheStrategyInterface $canCache = null)` |
||
550 | - Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` |
||
551 | |||
552 | 3.5 to 3.6 |
||
553 | ---------- |
||
554 | |||
555 | * Mixed casing of headers are now forced to be a single consistent casing across all values for that header. |
||
556 | * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution |
||
557 | * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). |
||
558 | For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader(). |
||
559 | Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request. |
||
560 | * Specific header implementations can be created for complex headers. When a message creates a header, it uses a |
||
561 | HeaderFactory which can map specific headers to specific header classes. There is now a Link header and |
||
562 | CacheControl header implementation. |
||
563 | * Moved getLinks() from Response to just be used on a Link header object. |
||
564 | |||
565 | If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the |
||
566 | HeaderInterface (e.g. toArray(), getAll(), etc.). |
||
567 | |||
568 | ### Interface changes |
||
569 | |||
570 | * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate |
||
571 | * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() |
||
572 | * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in |
||
573 | Guzzle\Http\Curl\RequestMediator |
||
574 | * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. |
||
575 | * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface |
||
576 | * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() |
||
577 | |||
578 | ### Removed deprecated functions |
||
579 | |||
580 | * Removed Guzzle\Parser\ParserRegister::get(). Use getParser() |
||
581 | * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). |
||
582 | |||
583 | ### Deprecations |
||
584 | |||
585 | * The ability to case-insensitively search for header values |
||
586 | * Guzzle\Http\Message\Header::hasExactHeader |
||
587 | * Guzzle\Http\Message\Header::raw. Use getAll() |
||
588 | * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object |
||
589 | instead. |
||
590 | |||
591 | ### Other changes |
||
592 | |||
593 | * All response header helper functions return a string rather than mixing Header objects and strings inconsistently |
||
594 | * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle |
||
595 | directly via interfaces |
||
596 | * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist |
||
597 | but are a no-op until removed. |
||
598 | * Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a |
||
599 | `Guzzle\Service\Command\ArrayCommandInterface`. |
||
600 | * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response |
||
601 | on a request while the request is still being transferred |
||
602 | * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess |
||
603 | |||
604 | 3.3 to 3.4 |
||
605 | ---------- |
||
606 | |||
607 | Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs. |
||
608 | |||
609 | 3.2 to 3.3 |
||
610 | ---------- |
||
611 | |||
612 | ### Response::getEtag() quote stripping removed |
||
613 | |||
614 | `Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header |
||
615 | |||
616 | ### Removed `Guzzle\Http\Utils` |
||
617 | |||
618 | The `Guzzle\Http\Utils` class was removed. This class was only used for testing. |
||
619 | |||
620 | ### Stream wrapper and type |
||
621 | |||
622 | `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase. |
||
623 | |||
624 | ### curl.emit_io became emit_io |
||
625 | |||
626 | Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the |
||
627 | 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' |
||
628 | |||
629 | 3.1 to 3.2 |
||
630 | ---------- |
||
631 | |||
632 | ### CurlMulti is no longer reused globally |
||
633 | |||
634 | Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added |
||
635 | to a single client can pollute requests dispatched from other clients. |
||
636 | |||
637 | If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the |
||
638 | ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is |
||
639 | created. |
||
640 | |||
641 | ```php |
||
642 | $multi = new Guzzle\Http\Curl\CurlMulti(); |
||
643 | $builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json'); |
||
644 | $builder->addListener('service_builder.create_client', function ($event) use ($multi) { |
||
645 | $event['client']->setCurlMulti($multi); |
||
646 | } |
||
647 | }); |
||
648 | ``` |
||
649 | |||
650 | ### No default path |
||
651 | |||
652 | URLs no longer have a default path value of '/' if no path was specified. |
||
653 | |||
654 | Before: |
||
655 | |||
656 | ```php |
||
657 | $request = $client->get('http://www.foo.com'); |
||
658 | echo $request->getUrl(); |
||
659 | // >> http://www.foo.com/ |
||
660 | ``` |
||
661 | |||
662 | After: |
||
663 | |||
664 | ```php |
||
665 | $request = $client->get('http://www.foo.com'); |
||
666 | echo $request->getUrl(); |
||
667 | // >> http://www.foo.com |
||
668 | ``` |
||
669 | |||
670 | ### Less verbose BadResponseException |
||
671 | |||
672 | The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and |
||
673 | response information. You can, however, get access to the request and response object by calling `getRequest()` or |
||
674 | `getResponse()` on the exception object. |
||
675 | |||
676 | ### Query parameter aggregation |
||
677 | |||
678 | Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a |
||
679 | setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is |
||
680 | responsible for handling the aggregation of multi-valued query string variables into a flattened hash. |
||
681 | |||
682 | 2.8 to 3.x |
||
683 | ---------- |
||
684 | |||
685 | ### Guzzle\Service\Inspector |
||
686 | |||
687 | Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig` |
||
688 | |||
689 | **Before** |
||
690 | |||
691 | ```php |
||
692 | use Guzzle\Service\Inspector; |
||
693 | |||
694 | class YourClient extends \Guzzle\Service\Client |
||
695 | { |
||
696 | public static function factory($config = array()) |
||
697 | { |
||
698 | $default = array(); |
||
699 | $required = array('base_url', 'username', 'api_key'); |
||
700 | $config = Inspector::fromConfig($config, $default, $required); |
||
701 | |||
702 | $client = new self( |
||
703 | $config->get('base_url'), |
||
704 | $config->get('username'), |
||
705 | $config->get('api_key') |
||
706 | ); |
||
707 | $client->setConfig($config); |
||
708 | |||
709 | $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); |
||
710 | |||
711 | return $client; |
||
712 | } |
||
713 | ``` |
||
714 | |||
715 | **After** |
||
716 | |||
717 | ```php |
||
718 | use Guzzle\Common\Collection; |
||
719 | |||
720 | class YourClient extends \Guzzle\Service\Client |
||
721 | { |
||
722 | public static function factory($config = array()) |
||
723 | { |
||
724 | $default = array(); |
||
725 | $required = array('base_url', 'username', 'api_key'); |
||
726 | $config = Collection::fromConfig($config, $default, $required); |
||
727 | |||
728 | $client = new self( |
||
729 | $config->get('base_url'), |
||
730 | $config->get('username'), |
||
731 | $config->get('api_key') |
||
732 | ); |
||
733 | $client->setConfig($config); |
||
734 | |||
735 | $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); |
||
736 | |||
737 | return $client; |
||
738 | } |
||
739 | ``` |
||
740 | |||
741 | ### Convert XML Service Descriptions to JSON |
||
742 | |||
743 | **Before** |
||
744 | |||
745 | ```xml |
||
746 | <?xml version="1.0" encoding="UTF-8"?> |
||
747 | <client> |
||
748 | <commands> |
||
749 | <!-- Groups --> |
||
750 | <command name="list_groups" method="GET" uri="groups.json"> |
||
751 | <doc>Get a list of groups</doc> |
||
752 | </command> |
||
753 | <command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'> |
||
754 | <doc>Uses a search query to get a list of groups</doc> |
||
755 | <param name="query" type="string" required="true" /> |
||
756 | </command> |
||
757 | <command name="create_group" method="POST" uri="groups.json"> |
||
758 | <doc>Create a group</doc> |
||
759 | <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/> |
||
760 | <param name="Content-Type" location="header" static="application/json"/> |
||
761 | </command> |
||
762 | <command name="delete_group" method="DELETE" uri="groups/{{id}}.json"> |
||
763 | <doc>Delete a group by ID</doc> |
||
764 | <param name="id" type="integer" required="true"/> |
||
765 | </command> |
||
766 | <command name="get_group" method="GET" uri="groups/{{id}}.json"> |
||
767 | <param name="id" type="integer" required="true"/> |
||
768 | </command> |
||
769 | <command name="update_group" method="PUT" uri="groups/{{id}}.json"> |
||
770 | <doc>Update a group</doc> |
||
771 | <param name="id" type="integer" required="true"/> |
||
772 | <param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/> |
||
773 | <param name="Content-Type" location="header" static="application/json"/> |
||
774 | </command> |
||
775 | </commands> |
||
776 | </client> |
||
777 | ``` |
||
778 | |||
779 | **After** |
||
780 | |||
781 | ```json |
||
782 | { |
||
783 | "name": "Zendesk REST API v2", |
||
784 | "apiVersion": "2012-12-31", |
||
785 | "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users", |
||
786 | "operations": { |
||
787 | "list_groups": { |
||
788 | "httpMethod":"GET", |
||
789 | "uri": "groups.json", |
||
790 | "summary": "Get a list of groups" |
||
791 | }, |
||
792 | "search_groups":{ |
||
793 | "httpMethod":"GET", |
||
794 | "uri": "search.json?query=\"{query} type:group\"", |
||
795 | "summary": "Uses a search query to get a list of groups", |
||
796 | "parameters":{ |
||
797 | "query":{ |
||
798 | "location": "uri", |
||
799 | "description":"Zendesk Search Query", |
||
800 | "type": "string", |
||
801 | "required": true |
||
802 | } |
||
803 | } |
||
804 | }, |
||
805 | "create_group": { |
||
806 | "httpMethod":"POST", |
||
807 | "uri": "groups.json", |
||
808 | "summary": "Create a group", |
||
809 | "parameters":{ |
||
810 | "data": { |
||
811 | "type": "array", |
||
812 | "location": "body", |
||
813 | "description":"Group JSON", |
||
814 | "filters": "json_encode", |
||
815 | "required": true |
||
816 | }, |
||
817 | "Content-Type":{ |
||
818 | "type": "string", |
||
819 | "location":"header", |
||
820 | "static": "application/json" |
||
821 | } |
||
822 | } |
||
823 | }, |
||
824 | "delete_group": { |
||
825 | "httpMethod":"DELETE", |
||
826 | "uri": "groups/{id}.json", |
||
827 | "summary": "Delete a group", |
||
828 | "parameters":{ |
||
829 | "id":{ |
||
830 | "location": "uri", |
||
831 | "description":"Group to delete by ID", |
||
832 | "type": "integer", |
||
833 | "required": true |
||
834 | } |
||
835 | } |
||
836 | }, |
||
837 | "get_group": { |
||
838 | "httpMethod":"GET", |
||
839 | "uri": "groups/{id}.json", |
||
840 | "summary": "Get a ticket", |
||
841 | "parameters":{ |
||
842 | "id":{ |
||
843 | "location": "uri", |
||
844 | "description":"Group to get by ID", |
||
845 | "type": "integer", |
||
846 | "required": true |
||
847 | } |
||
848 | } |
||
849 | }, |
||
850 | "update_group": { |
||
851 | "httpMethod":"PUT", |
||
852 | "uri": "groups/{id}.json", |
||
853 | "summary": "Update a group", |
||
854 | "parameters":{ |
||
855 | "id": { |
||
856 | "location": "uri", |
||
857 | "description":"Group to update by ID", |
||
858 | "type": "integer", |
||
859 | "required": true |
||
860 | }, |
||
861 | "data": { |
||
862 | "type": "array", |
||
863 | "location": "body", |
||
864 | "description":"Group JSON", |
||
865 | "filters": "json_encode", |
||
866 | "required": true |
||
867 | }, |
||
868 | "Content-Type":{ |
||
869 | "type": "string", |
||
870 | "location":"header", |
||
871 | "static": "application/json" |
||
872 | } |
||
873 | } |
||
874 | } |
||
875 | } |
||
876 | ``` |
||
877 | |||
878 | ### Guzzle\Service\Description\ServiceDescription |
||
879 | |||
880 | Commands are now called Operations |
||
881 | |||
882 | **Before** |
||
883 | |||
884 | ```php |
||
885 | use Guzzle\Service\Description\ServiceDescription; |
||
886 | |||
887 | $sd = new ServiceDescription(); |
||
888 | $sd->getCommands(); // @returns ApiCommandInterface[] |
||
889 | $sd->hasCommand($name); |
||
890 | $sd->getCommand($name); // @returns ApiCommandInterface|null |
||
891 | $sd->addCommand($command); // @param ApiCommandInterface $command |
||
892 | ``` |
||
893 | |||
894 | **After** |
||
895 | |||
896 | ```php |
||
897 | use Guzzle\Service\Description\ServiceDescription; |
||
898 | |||
899 | $sd = new ServiceDescription(); |
||
900 | $sd->getOperations(); // @returns OperationInterface[] |
||
901 | $sd->hasOperation($name); |
||
902 | $sd->getOperation($name); // @returns OperationInterface|null |
||
903 | $sd->addOperation($operation); // @param OperationInterface $operation |
||
904 | ``` |
||
905 | |||
906 | ### Guzzle\Common\Inflection\Inflector |
||
907 | |||
908 | Namespace is now `Guzzle\Inflection\Inflector` |
||
909 | |||
910 | ### Guzzle\Http\Plugin |
||
911 | |||
912 | Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below. |
||
913 | |||
914 | ### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log |
||
915 | |||
916 | Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively. |
||
917 | |||
918 | **Before** |
||
919 | |||
920 | ```php |
||
921 | use Guzzle\Common\Log\ClosureLogAdapter; |
||
922 | use Guzzle\Http\Plugin\LogPlugin; |
||
923 | |||
924 | /** @var \Guzzle\Http\Client */ |
||
925 | $client; |
||
926 | |||
927 | // $verbosity is an integer indicating desired message verbosity level |
||
928 | $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE); |
||
929 | ``` |
||
930 | |||
931 | **After** |
||
932 | |||
933 | ```php |
||
934 | use Guzzle\Log\ClosureLogAdapter; |
||
935 | use Guzzle\Log\MessageFormatter; |
||
936 | use Guzzle\Plugin\Log\LogPlugin; |
||
937 | |||
938 | /** @var \Guzzle\Http\Client */ |
||
939 | $client; |
||
940 | |||
941 | // $format is a string indicating desired message format -- @see MessageFormatter |
||
942 | $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT); |
||
943 | ``` |
||
944 | |||
945 | ### Guzzle\Http\Plugin\CurlAuthPlugin |
||
946 | |||
947 | Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`. |
||
948 | |||
949 | ### Guzzle\Http\Plugin\ExponentialBackoffPlugin |
||
950 | |||
951 | Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes. |
||
952 | |||
953 | **Before** |
||
954 | |||
955 | ```php |
||
956 | use Guzzle\Http\Plugin\ExponentialBackoffPlugin; |
||
957 | |||
958 | $backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge( |
||
959 | ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429) |
||
960 | )); |
||
961 | |||
962 | $client->addSubscriber($backoffPlugin); |
||
963 | ``` |
||
964 | |||
965 | **After** |
||
966 | |||
967 | ```php |
||
968 | use Guzzle\Plugin\Backoff\BackoffPlugin; |
||
969 | use Guzzle\Plugin\Backoff\HttpBackoffStrategy; |
||
970 | |||
971 | // Use convenient factory method instead -- see implementation for ideas of what |
||
972 | // you can do with chaining backoff strategies |
||
973 | $backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge( |
||
974 | HttpBackoffStrategy::getDefaultFailureCodes(), array(429) |
||
975 | )); |
||
976 | $client->addSubscriber($backoffPlugin); |
||
977 | ``` |
||
978 | |||
979 | ### Known Issues |
||
980 | |||
981 | #### [BUG] Accept-Encoding header behavior changed unintentionally. |
||
982 | |||
983 | (See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e) |
||
984 | |||
985 | In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to |
||
986 | properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen. |
||
987 | See issue #217 for a workaround, or use a version containing the fix. |