Guzzle has become the de facto standard HTTP library in PHP. In newer versions of the WordPress JSON API plugin, developers already moved away from the WP HTTP API and started using Guzzle instead. If you have never worked with Guzzle before, the examples below provide a quick practical introduction.
Sending Requests
You can send requests through a GuzzleHttpClient object.
Creating a Client
use GuzzleHttpClient;
$client = new Client([
'base_uri' => 'http://httpbin.org',
'timeout' => 2.0,
]);
Clients in Guzzle are immutable. After a client is created, you cannot change the default values configured for it. The Client constructor accepts an array of options.
base_uri
The base_uri option can be a string or a UriInterface instance. It is used to resolve relative URIs according to RFC 3986.
$client = new GuzzleHttpClient(['base_uri' => 'https://foo.com/api/']);
$response = $client->request('GET', 'test');
$response = $client->request('GET', '/root');
If you do not want to read the RFC, here are a few quick examples of how base_uri combines with other URIs:
| base_uri | URI | Result |
|---|---|---|
| http://foo.com | /bar | http://foo.com/bar |
| http://foo.com/foo | /bar | http://foo.com/bar |
| http://foo.com/foo | bar | http://foo.com/bar |
| http://foo.com/foo/ | bar | http://foo.com/foo/bar |
| http://foo.com | http://baz.com | http://baz.com |
| http://foo.com/?bar | bar | http://foo.com/bar |
handler
The handler option is the callback responsible for transferring HTTP requests. It receives a PSR-7 request object and an array of options, and must return a PromiseInterface that resolves to a PSR-7 response. Because handler is a constructor option, it cannot be overridden in per-request options.
Other options passed to the constructor become default request options for every request made with that client.
Making Requests
The methods on the Client object make it easy to send requests:
$response = $client->get('http://httpbin.org/get');
$response = $client->delete('http://httpbin.org/delete');
$response = $client->head('http://httpbin.org/get');
$response = $client->options('http://httpbin.org/get');
$response = $client->patch('http://httpbin.org/patch');
$response = $client->post('http://httpbin.org/post');
$response = $client->put('http://httpbin.org/put');
You can also build a request object first and then send it through the client:
use GuzzleHttpPsr7Request;
$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);
The client supports flexible request handling, including per-request options, middleware, and URI resolution based on the configured base URI. You can read more in the Handlers and Middleware documentation.
Asynchronous Requests
You can also create asynchronous requests by using the async variants of the client methods:
$promise = $client->getAsync('http://httpbin.org/get');
$promise = $client->deleteAsync('http://httpbin.org/delete');
$promise = $client->headAsync('http://httpbin.org/get');
$promise = $client->optionsAsync('http://httpbin.org/get');
$promise = $client->patchAsync('http://httpbin.org/patch');
$promise = $client->postAsync('http://httpbin.org/post');
$promise = $client->putAsync('http://httpbin.org/put');
You can also use sendAsync() and requestAsync():
use GuzzleHttpPsr7Request;
$headers = ['X-Foo' => 'Bar'];
$body = 'Hello!';
$request = new Request('HEAD', 'http://httpbin.org/head', $headers, $body);
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
These methods return Promise objects that follow the Promises/A+ specification from Guzzle’s promises library. That means you can attach success and failure handlers with then().
use PsrHttpMessageResponseInterface;
use GuzzleHttpExceptionRequestException;
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(
function (ResponseInterface $res) {
echo $res->getStatusCode() . "n";
},
function (RequestException $e) {
echo $e->getMessage() . "n";
echo $e->getRequest()->getMethod();
}
);
Concurrent Requests
You can combine Promises with asynchronous requests to send multiple requests at the same time:
use GuzzleHttpClient;
use GuzzleHttpPromise;
$client = new Client(['base_uri' => 'http://httpbin.org/']);
$promises = [
'image' => $client->getAsync('/image'),
'png' => $client->getAsync('/image/png'),
'jpeg' => $client->getAsync('/image/jpeg'),
'webp' => $client->getAsync('/image/webp')
];
$results = Promiseunwrap($promises);
echo $results['image']->getHeader('Content-Length');
echo $results['png']->getHeader('Content-Length');
If you need to send an unknown number of requests, you can use GuzzleHttpPool:
use GuzzleHttpPool;
use GuzzleHttpClient;
use GuzzleHttpPsr7Request;
$client = new Client();
$requests = function ($total) {
$uri = 'http://127.0.0.1:8126/guzzle-server/perf';
for ($i = 0; $i < $total; $i++) {
yield new Request('GET', $uri);
}
};
$pool = new Pool($client, $requests(100), [
'concurrency' => 5,
'fulfilled' => function ($response, $index) {
// called when each request succeeds
},
'rejected' => function ($reason, $index) {
// called when each request fails
},
]);
$promise = $pool->promise();
$promise->wait();
Working with Responses
In the examples above, we get a $response variable directly or receive a response from a Promise. The response object implements the PSR-7 ResponseInterface and contains a lot of useful information.
You can get the status code and reason phrase:
$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK
You can also work with headers:
if ($response->hasHeader('Content-Length')) {
echo "It exists";
}
echo $response->getHeader('Content-Length');
foreach ($response->getHeaders() as $name => $values) {
echo $name . ': ' . implode(', ', $values) . "rn";
}
Use getBody() to work with the response body as either a string or a stream:
$body = $response->getBody();
echo $body;
$stringBody = (string) $body;
$tenBytes = $body->read(10);
Once you understand the client, async requests, concurrency, and PSR-7 responses, Guzzle becomes a very powerful replacement for the WP HTTP API in advanced WordPress development work.
