2013-01-23 21:45:32 -06:00
|
|
|
Guzzle Upgrade Guide
|
|
|
|
====================
|
|
|
|
|
2014-02-09 18:10:20 -08:00
|
|
|
3.x to 4.0
|
|
|
|
----------
|
|
|
|
|
|
|
|
## Overarching changes:
|
|
|
|
|
|
|
|
- Now required PHP 5.4 or greater.
|
|
|
|
- No longer requires cURL to send requests.
|
|
|
|
- Guzzle no longer wraps every exception it throws. Only exceptions that are recoverable are now wrapped by Guzzle.
|
|
|
|
- Various namespaces have been removed or renamed.
|
|
|
|
- No longer requiring the Symfony EventDispatcher. A custom event dispatcher based on the Symfony EventDispatcher is
|
|
|
|
now utilized in `Guzzle\Common\EmitterInterface` (resulting in significant speed and functionality improvements).
|
|
|
|
- No longer breaking out the `Common`, `Http`, or `Stream` namespaces into subcomponents. These are now essentially
|
|
|
|
"Guzzle", and everything else will be considered an extension.
|
|
|
|
|
|
|
|
Changes per Guzzle 3.x namespace are described below.
|
|
|
|
|
|
|
|
## Batch
|
|
|
|
|
|
|
|
The `Guzzle\Batch` namespace has been removed. This is best left to third-parties to implement on top of Guzzle's
|
|
|
|
core HTTP library.
|
|
|
|
|
|
|
|
## Cache
|
|
|
|
|
|
|
|
The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement has been implemented yet, but hoping to
|
|
|
|
utilize a PSR cache interface).
|
|
|
|
|
|
|
|
## Common
|
|
|
|
|
|
|
|
- Removed all of the wrapped exceptions. It's better to use the standard PHP library for unrecoverable exceptions.
|
|
|
|
- `FromConfigInterface` has been removed.
|
|
|
|
- `Guzzle\Common\Version` has been removed. Be sure to require the `functions.php` file and then you can use the
|
|
|
|
`Guzzle\VERSION` constant.
|
|
|
|
|
|
|
|
### Collection
|
|
|
|
|
|
|
|
- `getAll` has been removed. Use `toArray` to convert a collection to an array.
|
|
|
|
- `inject` has been removed.
|
|
|
|
- `keySearch` has been removed.
|
|
|
|
- `getPath` no longer supports wildcard expressions. Use something better like JMESPath for this.
|
|
|
|
- `setPath` now supports appending to an existing array via the `[]` notation.
|
|
|
|
|
|
|
|
### Events
|
|
|
|
|
|
|
|
Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses `Guzzle\Common\Emitter`.
|
|
|
|
|
|
|
|
- `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by `Guzzle\Common\EmitterInterface`.
|
|
|
|
- `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by `Guzzle\Common\Emitter`.
|
|
|
|
- `Symfony\Component\EventDispatcher\Event` is replaced by `Guzzle\Common\Event`, and Guzzle now has an EventInterface
|
|
|
|
in `Guzzle\Common\EventInterface`.
|
|
|
|
- `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and `HasDispatcherInterface` has moved to
|
|
|
|
`HasEmitterInterface`. Retrieving the event emitter of a request, client, etc now uses the `getEmitter` method
|
|
|
|
rather than the `getDispatcher` method.
|
|
|
|
|
|
|
|
#### Emitter
|
|
|
|
|
|
|
|
- Use the `once()` method to add a listener that automatically removes itself the first time it is invoked.
|
|
|
|
- Use the `listeners` method to retrieve a list of event listeners rather than the `getListeners` method.
|
|
|
|
- Use `emit` instead of `dispatch` to emit an event from an emitter.
|
|
|
|
|
|
|
|
```php
|
|
|
|
// 3.x
|
|
|
|
$request->getEventDispatcher()->addSubscriber(new Mock());
|
|
|
|
// 4.x
|
|
|
|
$request->getEmitter()->addSubscriber(new Mock());
|
|
|
|
```
|
|
|
|
|
|
|
|
Use the `on()` method to add a listener rather than the `addListener` method.
|
|
|
|
|
|
|
|
```php
|
|
|
|
// 3.x
|
|
|
|
$request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } );
|
|
|
|
// 4.x
|
|
|
|
$request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } );
|
|
|
|
```
|
|
|
|
|
|
|
|
## Http
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
## Inflection
|
|
|
|
|
|
|
|
The `Guzzle\Inflection` namespace has been removed. This is not a core concern of Guzzle.
|
|
|
|
|
|
|
|
## Iterator
|
|
|
|
|
|
|
|
The `Guzzle\Iterator` namespace has been removed.
|
|
|
|
|
|
|
|
- `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and `Guzzle\Iterator\MethodProxyIterator` are
|
|
|
|
nice, but not a core requirement of Guzzle itself..
|
|
|
|
- `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent class is shipped with PHP 5.4.
|
|
|
|
- `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because it's easier to just wrap an iterator
|
|
|
|
in a generator that maps values.
|
|
|
|
|
|
|
|
## Log
|
|
|
|
|
|
|
|
The `Guzzle\Log` namespace has been removed. Guzzle now relies on `Psr\Log\LoggerInterface` for all logging.
|
|
|
|
The MessageFormatter class has been moved to `Guzzle\Plugin\Log\MessageFormatter`.
|
|
|
|
|
|
|
|
## Parser
|
|
|
|
|
|
|
|
The `Guzzle\Parser` namespace has been removed. This was previously used to parse cookies, messages, URI templates,
|
|
|
|
and URLs.
|
|
|
|
|
|
|
|
- Cookie: Cookie parsing logic has been moved to `Guzzle\Http\Subscriber\CookieJar\SetCookie::fromString`. Extending
|
|
|
|
cookie parsing is no longer possible (and was never really needed).
|
|
|
|
- Message: Message parsing logic for both requests and responses has been moved to
|
|
|
|
`Guzzle\Http\Message\MessageFactory::fromMessage`. Message parsing is only used in debugging or deserializing
|
|
|
|
messages, so it doesn't make sense for Guzzle as a library to add this level of complexity to parsing messages.
|
|
|
|
- UriTemplate: URI template parsing has been moved to `Guzzle\Url\UriTemplate`. The Guzzle library will automatically
|
|
|
|
use the PECL URI template library if it is installed.
|
|
|
|
- Url: URL parsing is now performed in `Guzzle\Http\Url\Url::fromString`. If custom URL parsing is necessary, then
|
|
|
|
developers are free to subclass `Guzzle\Url\Url`.
|
|
|
|
|
|
|
|
## Plugin
|
|
|
|
|
|
|
|
The `Guzzle\Plugin` namespace has been renamed to `Guzzle\Http\Subscriber`. Several plugins are shipping with the core
|
|
|
|
Guzzle library under `Guzzle\Http\Subscriber`:
|
|
|
|
|
|
|
|
- `Guzzle\Http\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar code has moved to
|
|
|
|
`Guzzle\Http\Subscriber\Cookie\CookieJar`.
|
|
|
|
- `Guzzle\Http\Subscriber\History`: Replaces the old HistoryPlugin.
|
|
|
|
- `Guzzle\Http\Subscriber\HttpError`: Throws errors when a bad HTTP response is received.
|
|
|
|
- `Guzzle\Http\Subscriber\Mock`: Replaces the old MockPlugin.
|
|
|
|
- `Guzzle\Http\Subscriber\PrepareRequestBody`: Prepares the body of a request just before sending.
|
|
|
|
- `Guzzle\Http\Subscriber\Redirect`: Replaces the RedirectPlugin.
|
|
|
|
|
|
|
|
The following plugins have been removed (third-parties are free to re-implement these if needed):
|
|
|
|
|
|
|
|
- `Guzzle\Plugin\Async` has been removed.
|
|
|
|
- `Guzzle\Plugin\CurlAuth` has been removed.
|
|
|
|
- `Guzzle\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed.
|
|
|
|
|
|
|
|
The following plugins are not part of the core Guzzle package, but are provided in separate repositories:
|
|
|
|
|
|
|
|
- `Guzzle\Plugin\BackoffPlugin` has been renamed to `Guzzle\Subscriber\Retry`. This plugin has been rewritten to be
|
|
|
|
much simpler to build custom retry policies using simple functions rather than various chained classes.
|
|
|
|
- `Guzzle\Plugin\Cache\CachePlugin` has moved to `Guzzle\Http\Subscriber\Cache\CacheSubscriber`.
|
|
|
|
- `Guzzle\Plugin\Log\LogPlugin` has moved to `Guzzle\Http\Subscriber\Log\LogSubscriber`.
|
|
|
|
- `Guzzle\Plugin\Md5\Md5Plugin` has moved to `Guzzle\Http\Subscriber\MessageIntegrity\MessageIntegritySubscriber`.
|
|
|
|
- `Guzzle\Plugin\Mock\MockPlugin` has moved to `Guzzle\Http\Subscriber\Mock\MockSubscriber`.
|
|
|
|
- `Guzzle\Plugin\Oauth\OauthPlugin` has moved to `Guzzle\Http\Subscriber\Oauth\OauthSubscriber`.
|
|
|
|
|
|
|
|
## Service
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
## Stream
|
|
|
|
|
|
|
|
`Guzzle\Stream\StreamInterface` has been given a large update to cleanly take on the responsibilities of
|
|
|
|
`Guzzle\Http\EntityBody` and `Guzzle\Http\EntityBodyInterface` now that they have been removed. The number of methods
|
|
|
|
implemented by the `StreamInterface` has been drastically reduced to allow developers to more easily extend and
|
|
|
|
decorate stream behavior.
|
|
|
|
|
|
|
|
## Removed methods from StreamInterface
|
|
|
|
|
|
|
|
- `getStream` and `setStream` have been removed to better encapsulate streams.
|
|
|
|
- `getMetadata` and `setMetadata` have been removed in favor of `Guzzle\Stream\MetadataStreamInterface`.
|
|
|
|
- `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been removed. This data is accessible when
|
|
|
|
using streams that implement `Guzzle\Stream\MetadataStreamInterface`.
|
|
|
|
- `rewind` has been removed. Use `seek(0)` for a similar behavior.
|
|
|
|
|
|
|
|
## Renamed methods
|
|
|
|
|
|
|
|
- `detachStream` has been renamed to `detach`.
|
|
|
|
- `feof` has been renamed to `eof`.
|
|
|
|
- `ftell` has been renamed to `tell`.
|
|
|
|
- `readLine` has moved from an instance method to a static class method of `Guzzle\Stream\Stream`.
|
|
|
|
|
|
|
|
## Metadata streams
|
|
|
|
|
|
|
|
`Guzzle\Stream\MetadataStreamInterface` has been added to denote streams that contain additonal metadata accessible
|
|
|
|
via `getMetadata()`. `Guzzle\Stream\StreamInterface::getMetadata` and `Guzzle\Stream\StreamInterface::setMetadata`
|
|
|
|
have been removed.
|
|
|
|
|
|
|
|
## SteamRequestFactory
|
|
|
|
|
|
|
|
The entire concept of the StreamRequestFactory has been removed. The way this was used in Guzzle 3 broke the actual
|
|
|
|
interface of sending streaming requests (instead of getting back a Response, you got a StreamInterface). Streeaming
|
|
|
|
PHP requests are now implemented throught the `Guzzle\Http\Adapter\StreamAdapter`.
|
|
|
|
|
2013-06-09 11:36:07 -07:00
|
|
|
3.6 to 3.7
|
|
|
|
----------
|
|
|
|
|
2013-06-09 11:38:04 -07:00
|
|
|
### Deprecations
|
2013-06-09 11:36:07 -07:00
|
|
|
|
|
|
|
- You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.:
|
|
|
|
|
|
|
|
```php
|
|
|
|
\Guzzle\Common\Version::$emitWarnings = true;
|
|
|
|
```
|
|
|
|
|
|
|
|
The following APIs and options have been marked as deprecated:
|
|
|
|
|
|
|
|
- Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead.
|
|
|
|
- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
|
|
|
- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
|
|
|
- Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
|
|
|
|
- Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
|
|
|
|
- Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
|
|
|
|
- Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
|
|
|
|
- Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
|
|
|
|
- Marked `Guzzle\Common\Collection::inject()` as deprecated.
|
2013-06-10 17:17:36 -07:00
|
|
|
- Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use
|
|
|
|
`$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or
|
|
|
|
`$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));`
|
2013-06-09 11:36:07 -07:00
|
|
|
|
|
|
|
3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational
|
|
|
|
request methods. When paired with a client's configuration settings, these options allow you to specify default settings
|
|
|
|
for various aspects of a request. Because these options make other previous configuration options redundant, several
|
|
|
|
configuration options and methods of a client and AbstractCommand have been deprecated.
|
|
|
|
|
2013-06-10 17:17:36 -07:00
|
|
|
- Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`.
|
|
|
|
- Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`.
|
|
|
|
- Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')`
|
2013-06-09 11:36:07 -07:00
|
|
|
- Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0
|
|
|
|
|
2013-06-09 11:37:05 -07:00
|
|
|
$command = $client->getCommand('foo', array(
|
|
|
|
'command.headers' => array('Test' => '123'),
|
|
|
|
'command.response_body' => '/path/to/file'
|
|
|
|
));
|
2013-06-09 11:36:07 -07:00
|
|
|
|
2013-06-09 11:37:05 -07:00
|
|
|
// Should be changed to:
|
2013-06-09 11:36:07 -07:00
|
|
|
|
2013-06-09 11:37:05 -07:00
|
|
|
$command = $client->getCommand('foo', array(
|
|
|
|
'command.request_options' => array(
|
|
|
|
'headers' => array('Test' => '123'),
|
|
|
|
'save_as' => '/path/to/file'
|
|
|
|
)
|
|
|
|
));
|
2013-06-09 11:36:07 -07:00
|
|
|
|
|
|
|
### Interface changes
|
|
|
|
|
|
|
|
Additions and changes (you will need to update any implementations or subclasses you may have created):
|
|
|
|
|
|
|
|
- Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
|
|
|
|
createRequest, head, delete, put, patch, post, options, prepareRequest
|
|
|
|
- Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
|
|
|
|
- Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
|
|
|
|
- Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
|
|
|
|
`Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
|
|
|
|
resource, string, or EntityBody into the $options parameter to specify the download location of the response.
|
|
|
|
- Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
|
|
|
|
default `array()`
|
|
|
|
- Added `Guzzle\Stream\StreamInterface::isRepeatable`
|
2013-06-09 13:41:02 -07:00
|
|
|
- Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
|
2013-06-09 11:36:07 -07:00
|
|
|
|
|
|
|
The following methods were removed from interfaces. All of these methods are still available in the concrete classes
|
|
|
|
that implement them, but you should update your code to use alternative methods:
|
|
|
|
|
|
|
|
- Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
|
|
|
|
`$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
|
2013-06-10 17:17:36 -07:00
|
|
|
`$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or
|
|
|
|
`$client->setDefaultOption('headers/{header_name}', 'value')`. or
|
|
|
|
`$client->setDefaultOption('headers', array('header_name' => 'value'))`.
|
2013-06-09 11:36:07 -07:00
|
|
|
- Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`.
|
|
|
|
- Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail.
|
|
|
|
- Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail.
|
|
|
|
- Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail.
|
|
|
|
- Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin.
|
|
|
|
- Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin.
|
|
|
|
- Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin.
|
|
|
|
|
2013-06-09 11:37:05 -07:00
|
|
|
### Cache plugin breaking changes
|
2013-06-09 11:36:07 -07:00
|
|
|
|
|
|
|
- CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
|
|
|
|
CacheStorageInterface. These two objects and interface will be removed in a future version.
|
|
|
|
- Always setting X-cache headers on cached responses
|
|
|
|
- Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
|
|
|
|
- `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
|
|
|
|
$request, Response $response);`
|
|
|
|
- `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
|
|
|
|
- `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
|
|
|
|
- Added `CacheStorageInterface::purge($url)`
|
|
|
|
- `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
|
|
|
|
$plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
|
|
|
|
CanCacheStrategyInterface $canCache = null)`
|
|
|
|
- Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
|
|
|
|
|
2013-05-29 21:00:22 -07:00
|
|
|
3.5 to 3.6
|
|
|
|
----------
|
|
|
|
|
|
|
|
* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
|
|
|
|
* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
|
|
|
|
* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
|
|
|
|
For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader().
|
|
|
|
Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request.
|
|
|
|
* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
|
|
|
|
HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
|
|
|
|
CacheControl header implementation.
|
|
|
|
* Moved getLinks() from Response to just be used on a Link header object.
|
|
|
|
|
|
|
|
If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the
|
|
|
|
HeaderInterface (e.g. toArray(), getAll(), etc).
|
|
|
|
|
2013-06-09 11:40:03 -07:00
|
|
|
### Interface changes
|
2013-05-29 21:00:22 -07:00
|
|
|
|
|
|
|
* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
|
|
|
|
* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
|
|
|
|
* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
|
|
|
|
Guzzle\Http\Curl\RequestMediator
|
|
|
|
* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
|
|
|
|
* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
|
|
|
|
* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
|
|
|
|
|
2013-06-09 11:40:03 -07:00
|
|
|
### Removed deprecated functions
|
2013-05-29 21:00:22 -07:00
|
|
|
|
|
|
|
* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
|
|
|
|
* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
|
|
|
|
|
2013-06-09 11:40:03 -07:00
|
|
|
### Deprecations
|
2013-06-09 11:39:36 -07:00
|
|
|
|
|
|
|
* The ability to case-insensitively search for header values
|
|
|
|
* Guzzle\Http\Message\Header::hasExactHeader
|
|
|
|
* Guzzle\Http\Message\Header::raw. Use getAll()
|
|
|
|
* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
|
|
|
|
instead.
|
|
|
|
|
2013-06-09 11:40:03 -07:00
|
|
|
### Other changes
|
2013-05-29 21:00:22 -07:00
|
|
|
|
|
|
|
* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
|
|
|
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
|
|
|
|
directly via interfaces
|
|
|
|
* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
|
|
|
but are a no-op until removed.
|
2014-02-09 18:10:20 -08:00
|
|
|
* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a
|
2013-05-29 21:00:22 -07:00
|
|
|
`Guzzle\Service\Command\ArrayCommandInterface`.
|
|
|
|
* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
|
|
|
|
on a request while the request is still being transferred
|
2013-05-29 22:02:44 -07:00
|
|
|
* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
|
2013-05-29 21:00:22 -07:00
|
|
|
|
2013-04-11 22:58:15 -07:00
|
|
|
3.3 to 3.4
|
|
|
|
----------
|
|
|
|
|
|
|
|
Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs.
|
|
|
|
|
2013-03-03 16:41:45 -08:00
|
|
|
3.2 to 3.3
|
|
|
|
----------
|
|
|
|
|
|
|
|
### Response::getEtag() quote stripping removed
|
|
|
|
|
|
|
|
`Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header
|
|
|
|
|
|
|
|
### Removed `Guzzle\Http\Utils`
|
|
|
|
|
|
|
|
The `Guzzle\Http\Utils` class was removed. This class was only used for testing.
|
|
|
|
|
|
|
|
### Stream wrapper and type
|
|
|
|
|
|
|
|
`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to lowercase.
|
|
|
|
|
|
|
|
### curl.emit_io became emit_io
|
|
|
|
|
|
|
|
Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the
|
|
|
|
'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
|
|
|
|
|
2013-02-12 22:55:52 -08:00
|
|
|
3.1 to 3.2
|
|
|
|
----------
|
|
|
|
|
|
|
|
### CurlMulti is no longer reused globally
|
|
|
|
|
|
|
|
Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added
|
|
|
|
to a single client can pollute requests dispatched from other clients.
|
|
|
|
|
|
|
|
If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the
|
|
|
|
ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is
|
|
|
|
created.
|
|
|
|
|
|
|
|
```php
|
|
|
|
$multi = new Guzzle\Http\Curl\CurlMulti();
|
|
|
|
$builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json');
|
|
|
|
$builder->addListener('service_builder.create_client', function ($event) use ($multi) {
|
|
|
|
$event['client']->setCurlMulti($multi);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
### No default path
|
|
|
|
|
|
|
|
URLs no longer have a default path value of '/' if no path was specified.
|
|
|
|
|
|
|
|
Before:
|
|
|
|
|
|
|
|
```php
|
|
|
|
$request = $client->get('http://www.foo.com');
|
|
|
|
echo $request->getUrl();
|
|
|
|
// >> http://www.foo.com/
|
|
|
|
```
|
|
|
|
|
|
|
|
After:
|
|
|
|
|
|
|
|
```php
|
|
|
|
$request = $client->get('http://www.foo.com');
|
|
|
|
echo $request->getUrl();
|
|
|
|
// >> http://www.foo.com
|
|
|
|
```
|
|
|
|
|
|
|
|
### Less verbose BadResponseException
|
|
|
|
|
|
|
|
The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and
|
|
|
|
response information. You can, however, get access to the request and response object by calling `getRequest()` or
|
|
|
|
`getResponse()` on the exception object.
|
|
|
|
|
2013-02-13 23:28:44 -08:00
|
|
|
|
|
|
|
### Query parameter aggregation
|
|
|
|
|
|
|
|
Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a
|
|
|
|
setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is
|
|
|
|
responsible for handling the aggregation of multi-valued query string variables into a flattened hash.
|
|
|
|
|
2013-01-23 21:45:32 -06:00
|
|
|
2.8 to 3.x
|
|
|
|
----------
|
|
|
|
|
|
|
|
### Guzzle\Service\Inspector
|
|
|
|
|
|
|
|
Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig`
|
|
|
|
|
|
|
|
**Before**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Service\Inspector;
|
|
|
|
|
|
|
|
class YourClient extends \Guzzle\Service\Client
|
|
|
|
{
|
|
|
|
public static function factory($config = array())
|
|
|
|
{
|
|
|
|
$default = array();
|
|
|
|
$required = array('base_url', 'username', 'api_key');
|
|
|
|
$config = Inspector::fromConfig($config, $default, $required);
|
|
|
|
|
|
|
|
$client = new self(
|
|
|
|
$config->get('base_url'),
|
|
|
|
$config->get('username'),
|
|
|
|
$config->get('api_key')
|
|
|
|
);
|
|
|
|
$client->setConfig($config);
|
|
|
|
|
|
|
|
$client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
|
|
|
|
|
|
|
|
return $client;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
**After**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Common\Collection;
|
|
|
|
|
|
|
|
class YourClient extends \Guzzle\Service\Client
|
|
|
|
{
|
|
|
|
public static function factory($config = array())
|
|
|
|
{
|
|
|
|
$default = array();
|
|
|
|
$required = array('base_url', 'username', 'api_key');
|
|
|
|
$config = Collection::fromConfig($config, $default, $required);
|
|
|
|
|
|
|
|
$client = new self(
|
|
|
|
$config->get('base_url'),
|
|
|
|
$config->get('username'),
|
|
|
|
$config->get('api_key')
|
|
|
|
);
|
|
|
|
$client->setConfig($config);
|
|
|
|
|
|
|
|
$client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json'));
|
|
|
|
|
|
|
|
return $client;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Convert XML Service Descriptions to JSON
|
|
|
|
|
|
|
|
**Before**
|
|
|
|
|
|
|
|
```xml
|
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
<client>
|
|
|
|
<commands>
|
|
|
|
<!-- Groups -->
|
|
|
|
<command name="list_groups" method="GET" uri="groups.json">
|
|
|
|
<doc>Get a list of groups</doc>
|
|
|
|
</command>
|
|
|
|
<command name="search_groups" method="GET" uri='search.json?query="{{query}} type:group"'>
|
|
|
|
<doc>Uses a search query to get a list of groups</doc>
|
|
|
|
<param name="query" type="string" required="true" />
|
|
|
|
</command>
|
|
|
|
<command name="create_group" method="POST" uri="groups.json">
|
|
|
|
<doc>Create a group</doc>
|
|
|
|
<param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
|
|
|
|
<param name="Content-Type" location="header" static="application/json"/>
|
|
|
|
</command>
|
|
|
|
<command name="delete_group" method="DELETE" uri="groups/{{id}}.json">
|
|
|
|
<doc>Delete a group by ID</doc>
|
|
|
|
<param name="id" type="integer" required="true"/>
|
|
|
|
</command>
|
|
|
|
<command name="get_group" method="GET" uri="groups/{{id}}.json">
|
|
|
|
<param name="id" type="integer" required="true"/>
|
|
|
|
</command>
|
|
|
|
<command name="update_group" method="PUT" uri="groups/{{id}}.json">
|
|
|
|
<doc>Update a group</doc>
|
|
|
|
<param name="id" type="integer" required="true"/>
|
|
|
|
<param name="data" type="array" location="body" filters="json_encode" doc="Group JSON"/>
|
|
|
|
<param name="Content-Type" location="header" static="application/json"/>
|
|
|
|
</command>
|
|
|
|
</commands>
|
|
|
|
</client>
|
|
|
|
```
|
|
|
|
|
|
|
|
**After**
|
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
|
|
|
"name": "Zendesk REST API v2",
|
|
|
|
"apiVersion": "2012-12-31",
|
|
|
|
"description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users",
|
|
|
|
"operations": {
|
|
|
|
"list_groups": {
|
|
|
|
"httpMethod":"GET",
|
|
|
|
"uri": "groups.json",
|
|
|
|
"summary": "Get a list of groups"
|
|
|
|
},
|
|
|
|
"search_groups":{
|
|
|
|
"httpMethod":"GET",
|
|
|
|
"uri": "search.json?query=\"{query} type:group\"",
|
|
|
|
"summary": "Uses a search query to get a list of groups",
|
|
|
|
"parameters":{
|
|
|
|
"query":{
|
|
|
|
"location": "uri",
|
|
|
|
"description":"Zendesk Search Query",
|
|
|
|
"type": "string",
|
|
|
|
"required": true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"create_group": {
|
|
|
|
"httpMethod":"POST",
|
|
|
|
"uri": "groups.json",
|
|
|
|
"summary": "Create a group",
|
|
|
|
"parameters":{
|
|
|
|
"data": {
|
|
|
|
"type": "array",
|
|
|
|
"location": "body",
|
|
|
|
"description":"Group JSON",
|
|
|
|
"filters": "json_encode",
|
|
|
|
"required": true
|
|
|
|
},
|
|
|
|
"Content-Type":{
|
|
|
|
"type": "string",
|
|
|
|
"location":"header",
|
|
|
|
"static": "application/json"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"delete_group": {
|
|
|
|
"httpMethod":"DELETE",
|
|
|
|
"uri": "groups/{id}.json",
|
|
|
|
"summary": "Delete a group",
|
|
|
|
"parameters":{
|
|
|
|
"id":{
|
|
|
|
"location": "uri",
|
|
|
|
"description":"Group to delete by ID",
|
|
|
|
"type": "integer",
|
|
|
|
"required": true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"get_group": {
|
|
|
|
"httpMethod":"GET",
|
|
|
|
"uri": "groups/{id}.json",
|
|
|
|
"summary": "Get a ticket",
|
|
|
|
"parameters":{
|
|
|
|
"id":{
|
|
|
|
"location": "uri",
|
|
|
|
"description":"Group to get by ID",
|
|
|
|
"type": "integer",
|
|
|
|
"required": true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"update_group": {
|
|
|
|
"httpMethod":"PUT",
|
|
|
|
"uri": "groups/{id}.json",
|
|
|
|
"summary": "Update a group",
|
|
|
|
"parameters":{
|
|
|
|
"id": {
|
|
|
|
"location": "uri",
|
|
|
|
"description":"Group to update by ID",
|
|
|
|
"type": "integer",
|
|
|
|
"required": true
|
|
|
|
},
|
|
|
|
"data": {
|
|
|
|
"type": "array",
|
|
|
|
"location": "body",
|
|
|
|
"description":"Group JSON",
|
|
|
|
"filters": "json_encode",
|
|
|
|
"required": true
|
|
|
|
},
|
|
|
|
"Content-Type":{
|
|
|
|
"type": "string",
|
|
|
|
"location":"header",
|
|
|
|
"static": "application/json"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Guzzle\Service\Description\ServiceDescription
|
|
|
|
|
|
|
|
Commands are now called Operations
|
|
|
|
|
|
|
|
**Before**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Service\Description\ServiceDescription;
|
|
|
|
|
|
|
|
$sd = new ServiceDescription();
|
|
|
|
$sd->getCommands(); // @returns ApiCommandInterface[]
|
|
|
|
$sd->hasCommand($name);
|
|
|
|
$sd->getCommand($name); // @returns ApiCommandInterface|null
|
|
|
|
$sd->addCommand($command); // @param ApiCommandInterface $command
|
|
|
|
```
|
|
|
|
|
|
|
|
**After**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Service\Description\ServiceDescription;
|
|
|
|
|
|
|
|
$sd = new ServiceDescription();
|
|
|
|
$sd->getOperations(); // @returns OperationInterface[]
|
|
|
|
$sd->hasOperation($name);
|
|
|
|
$sd->getOperation($name); // @returns OperationInterface|null
|
|
|
|
$sd->addOperation($operation); // @param OperationInterface $operation
|
|
|
|
```
|
|
|
|
|
|
|
|
### Guzzle\Common\Inflection\Inflector
|
|
|
|
|
|
|
|
Namespace is now `Guzzle\Inflection\Inflector`
|
|
|
|
|
|
|
|
### Guzzle\Http\Plugin
|
|
|
|
|
|
|
|
Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below.
|
|
|
|
|
|
|
|
### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log
|
|
|
|
|
|
|
|
Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively.
|
|
|
|
|
|
|
|
**Before**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Common\Log\ClosureLogAdapter;
|
|
|
|
use Guzzle\Http\Plugin\LogPlugin;
|
|
|
|
|
|
|
|
/** @var \Guzzle\Http\Client */
|
|
|
|
$client;
|
|
|
|
|
|
|
|
// $verbosity is an integer indicating desired message verbosity level
|
|
|
|
$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE);
|
|
|
|
```
|
|
|
|
|
|
|
|
**After**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Log\ClosureLogAdapter;
|
|
|
|
use Guzzle\Log\MessageFormatter;
|
|
|
|
use Guzzle\Plugin\Log\LogPlugin;
|
|
|
|
|
|
|
|
/** @var \Guzzle\Http\Client */
|
|
|
|
$client;
|
|
|
|
|
|
|
|
// $format is a string indicating desired message format -- @see MessageFormatter
|
|
|
|
$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT);
|
|
|
|
```
|
|
|
|
|
|
|
|
### Guzzle\Http\Plugin\CurlAuthPlugin
|
|
|
|
|
|
|
|
Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`.
|
|
|
|
|
|
|
|
### Guzzle\Http\Plugin\ExponentialBackoffPlugin
|
|
|
|
|
|
|
|
Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes.
|
|
|
|
|
|
|
|
**Before**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Http\Plugin\ExponentialBackoffPlugin;
|
|
|
|
|
|
|
|
$backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge(
|
|
|
|
ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429)
|
|
|
|
));
|
|
|
|
|
|
|
|
$client->addSubscriber($backoffPlugin);
|
|
|
|
```
|
|
|
|
|
|
|
|
**After**
|
|
|
|
|
|
|
|
```php
|
|
|
|
use Guzzle\Plugin\Backoff\BackoffPlugin;
|
|
|
|
use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
|
|
|
|
|
|
|
|
// Use convenient factory method instead -- see implementation for ideas of what
|
|
|
|
// you can do with chaining backoff strategies
|
|
|
|
$backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge(
|
|
|
|
HttpBackoffStrategy::getDefaultFailureCodes(), array(429)
|
|
|
|
));
|
|
|
|
$client->addSubscriber($backoffPlugin);
|
2013-01-23 21:51:55 -06:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Known Issues
|
|
|
|
|
2013-02-12 22:55:52 -08:00
|
|
|
#### [BUG] Accept-Encoding header behavior changed unintentionally.
|
2013-01-23 21:53:25 -06:00
|
|
|
|
|
|
|
(See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e)
|
2013-01-23 21:51:55 -06:00
|
|
|
|
|
|
|
In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to
|
|
|
|
properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen.
|
2013-01-23 21:53:25 -06:00
|
|
|
See issue #217 for a workaround, or use a version containing the fix.
|