Plugins¶
Guzzle ships with a number of plugins that typically deal with the Guzzle\Http namespace.
Note
Any event subscriber attached to the EventDispatcher of a Guzzle\Http\Client or Guzzle\Service\Client object will automatically be attached to all request objects created by the client. This allows you to attach, for example, a HistoryPlugin to a client object, and from that point on, every request sent through that client will utilize the HistoryPlugin.
Guzzle provides easy to use request plugins that add behavior to requests based on signal slot event notifications.
Log plugin¶
Use the Guzzle\Plugin\Log\LogPlugin to view all data sent over the wire, including entity bodies and redirects.
use Guzzle\Http\Client;
use Guzzle\Log\Zf1LogAdapter;
use Guzzle\Plugin\Log\LogPlugin;
use Guzzle\Log\MessageFormatter;
$client = new Client('http://www.test.com/');
$adapter = new Zf1LogAdapter(
new \Zend_Log(new \Zend_Log_Writer_Stream('php://output'))
);
$logPlugin = new LogPlugin($adapter, MessageFormatter::DEBUG_FORMAT);
// Attach the plugin to the client, which will in turn be attached to all
// requests generated by the client
$client->addSubscriber($logPlugin);
$response = $client->get('http://google.com')->send();
The code sample above wraps a Zend_Log object using a Guzzle\Log\Zf1LogAdapter. After attaching the plugin to the client, all data sent over the wire will be logged to stdout.
The first argument of the LogPlugin’s constructor accepts a Guzzle\Log\LogAdapterInterface object. This object is an adapter that allows you to use the logging capabilities of your favorite log implementation. The second argument of the constructor accepts a Guzzle\Log\MessageFormatter or a log messaged format string. The format string uses variable substitution and allows you to define the log data that is important to your application. The different variables that can be injected are as follows:
| Variable | Substitution |
|---|---|
| {request} | Full HTTP request message |
| {response} | Full HTTP response message |
| {ts} | Timestamp |
| {host} | Host of the request |
| {method} | Method of the request |
| {url} | URL of the request |
| {host} | Host of the request |
| {protocol} | Request protocol |
| {version} | Protocol version |
| {resource} | Resource of the request (path + query + fragment) |
| {port} | Port of the request |
| {hostname} | Hostname of the machine that sent the request |
| {code} | Status code of the response (if available) |
| {phrase} | Reason phrase of the response (if available) |
| {curl_error} | Curl error message (if available) |
| {curl_code} | Curl error code (if available) |
| {curl_stderr} | Curl standard error (if available) |
| {connect_time} | Time in seconds it took to establish the connection (if available) |
| {total_time} | Total transaction time in seconds for last transfer (if available) |
| {req_header_*} | Replace * with the lowercased name of a request header to add to the message |
| {res_header_*} | Replace * with the lowercased name of a response header to add to the message |
| {req_body} | Request body |
| {res_body} | Response body |
The LogPlugin has a helper method that can be used when debugging that will output the full HTTP request and response of a transaction:
$client->addSubscriber(LogPlugin::getDebugPlugin());
Backoff Plugin¶
The Guzzle\Plugin\Backoff\BackoffPlugin automatically retries failed HTTP requests using custom backoff strategies:
use Guzzle\Http\Client;
use Guzzle\Plugin\Backoff\BackoffPlugin;
$client = new Client('http://www.test.com/');
// Use a static factory method to get a backoff plugin using the exponential backoff strategy
$backoffPlugin = BackoffPlugin::getExponentialBackoff();
// Add the backoff plugin to the client object
$client->addSubscriber($backoffPlugin);
The BackoffPlugin’s constructor accepts a Guzzle\Plugin\Backoff\BackoffStrategyInterface object that is used to determine when a retry should be issued and how long to delay between retries. The above code example shows how to attach a BackoffPlugn to a client that is pre-configured to retry failed 500 and 503 responses using truncated exponential backoff (emulating the behavior of Guzzle 2’s ExponentialBackoffPlugin).
Cache plugin¶
Guzzle can leverage HTTP’s caching specifications using the Guzzle\Plugin\Cache\CachePlugin. The CachePlugin provides a private transparent proxy cache that caches HTTP responses. The caching logic, based on RFC 2616, uses HTTP headers to control caching behavior, cache lifetime, and supports ETag and Last-Modified based revalidation:
use Guzzle\Http\Client;
use Doctrine\Common\Cache\ArrayCache;
use Guzzle\Common\Cache\DoctrineCacheAdapter;
use Guzzle\Plugin\Cache\CachePlugin;
$client = new Client('http://www.test.com/');
$cachePlugin = new CachePlugin(array(
'adapter' => new DoctrineCacheAdapter(new ArrayCache())
));
// Add the cache plugin to the client object
$client->addSubscriber($cachePlugin);
$client->get('http://www.wikipedia.org/')->send();
// The next request will revalidate against the origin server to see if it
// has been modified. If a 304 response is received the response will be
// served from cache
$client->get('http://www.wikipedia.org/')->send();
Guzzle doesn’t try to reinvent the wheel when it comes to caching or logging. Plenty of other frameworks have excellent solutions in place that you are probably already using in your applications. Guzzle uses adapters for caching and logging. Guzzle currently supports log adapters for the Zend Framework 1.0/2.0 and Monolog, and cache adapters for Doctrine 2.0 and the Zend Framework 1.0/2.0.
See Caching for more information on the caching plugin.
Cookie plugin¶
Some web services require a Cookie in order to maintain a session. The Guzzle\Plugin\Cookie\CookiePlugin will add cookies to requests and parse cookies from responses using a CookieJar object:
use Guzzle\Http\Client;
use Guzzle\Plugin\Cookie\CookiePlugin;
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
$cookiePlugin = new CookiePlugin(new ArrayCookieJar());
// Add the cookie plugin to a client
$client = new Client('http://www.test.com/');
$client->addSubscriber($cookiePlugin);
// Send the request with no cookies and parse the returned cookies
$client->get('http://www.yahoo.com/')->send();
// Send the request again, noticing that cookies are being sent
$request = $client->get('http://www.yahoo.com/');
$request->send();
echo $request;
You can disable cookies per-request by setting the cookies.disable value to true on a request’s params object.
$request->getParams()->set('cookies.disable', true);
MD5 validator plugin¶
Entity bodies can sometimes be modified over the wire due to a faulty TCP transport or misbehaving proxy. If an HTTP response contains a Content-MD5 header, then a MD5 hash of the entity body of a response can be compared against the Content-MD5 header of the response to determine if the response was delivered intact. The Guzzle\Plugin\Md5\Md5ValidatorPlugin will throw an UnexpectedValueException if the calculated MD5 hash does not match the Content-MD5 header value:
use Guzzle\Http\Client;
use Guzzle\Plugin\Md5\Md5ValidatorPlugin;
$client = new Client('http://www.test.com/');
$md5Plugin = new Md5ValidatorPlugin();
// Add the md5 plugin to the client object
$client->addSubscriber($md5Plugin);
$request = $client->get('http://www.yahoo.com/');
$request->send();
Calculating the MD5 hash of a large entity body or an entity body that was transferred using a Content-Encoding is an expensive operation. When working in high performance applications, you might consider skipping the MD5 hash validation for entity bodies bigger than a certain size or Content-Encoded entity bodies (see Guzzle\Plugin\Md5\Md5ValidatorPlugin for more information).
History plugin¶
The history plugin tracks all of the requests and responses sent through a request or client. This plugin can be useful for crawling or unit testing. By default, the history plugin stores up to 10 requests and responses.
use Guzzle\Http\Client;
use Guzzle\Plugin\History\HistoryPlugin;
$client = new Client('http://www.test.com/');
// Add the history plugin to the client object
$history = new HistoryPlugin();
$history->setLimit(5);
$client->addSubscriber($history);
$client->get('http://www.yahoo.com/')->send();
echo $history->getLastRequest();
echo $history->getLastResponse();
echo count($history);
Mock Plugin¶
The mock plugin is useful for testing Guzzle clients. The mock plugin allows you to queue an array of responses that will satisfy requests sent from a client by consuming the request queue in FIFO order.
use Guzzle\Http\Client;
use Guzzle\Plugin\Mock\MockPlugin;
use Guzzle\Http\Message\Response;
$client = new Client('http://www.test.com/');
$mock = new MockPlugin();
$mock->addResponse(new Response(200))
->addResponse(new Response(404));
// Add the mock plugin to the client object
$client->addSubscriber($mock);
// The following request will receive a 200 response from the plugin
$client->get('http://www.example.com/')->send();
// The following request will receive a 404 response from the plugin
$client->get('http://www.test.com/')->send();
Curl Auth Plugin¶
If your web service client requires basic authorization, then you can use the CurlAuthPlugin to easily add an Authorization header to each request sent by the client.
use Guzzle\Http\Client;
use Guzzle\Plugin\CurlAuth\CurlAuthPlugin;
$client = new Client('http://www.test.com/');
// Add the auth plugin to the client object
$authPlugin = new CurlAuthPlugin('username', 'password');
$client->addSubscriber($authPlugin);
$response = $client->get('projects/1/people')->send();
$xml = new SimpleXMLElement($response->getBody(true));
foreach ($xml->person as $person) {
echo $person->email . "\n";
}
OAuth 1.0 Plugin¶
Guzzle ships with an OAuth 1.0 plugin that can sign requests using a consumer key, consumer secret, OAuth token, and OAuth secret. Here’s an example showing how to send an authenticated request to the Twitter REST API:
use Guzzle\Http\Client;
use Guzzle\Plugin\Oauth\OauthPlugin;
$client = new Client('http://api.twitter.com/1');
$oauth = new OauthPlugin(array(
'consumer_key' => 'my_key',
'consumer_secret' => 'my_secret',
'token' => 'my_token',
'token_secret' => 'my_token_secret'
));
$client->addSubscriber($oauth);
$response = $client->get('statuses/public_timeline.json')->send();
If you need to use a custom signing method, you can pass a signature_method configuration option in the constructor of the OAuth plugin. The signature_method option must be a callable variable that accepts a string to sign and signing key and returns a signed string.
Note
You can omit the token and token_secret options to use two-legged OAuth.
Async Plugin¶
The AsyncPlugin allows you to send requests that do not wait on a response. This is handled through cURL by utilizing the progress event. When a request has sent all of its data to the remote server, Guzzle adds a 1ms timeout on the request and instructs cURL to not download the body of the response. The async plugin then catches the exception and adds a mock response to the request, along with an X-Guzzle-Async header to let you know that the response was not fully downloaded.
use Guzzle\Http\Client;
use Guzzle\Plugin\Async\AsyncPlugin;
$client = new Client('http://www.example.com');
$client->addSubscriber(new AsyncPlugin());
$response = $client->get()->send();