← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Guzzle HTTP Client

php PHP 7.2+ Intermediate

Also Known As

Guzzle GuzzleHttp PHP HTTP client PSR-18

TL;DR

Guzzle is PHP's most popular HTTP client library — providing a clean API for making synchronous and asynchronous HTTP requests, handling middleware, retries, authentication, and multipart uploads, with PSR-7 and PSR-18 compliance.

Explanation

Guzzle wraps PHP's cURL extension and stream wrappers with a clean object-oriented interface. A Client instance is configured with a base URI and default options; requests are made with get(), post(), request(), or sendAsync() for async operations. Middleware stacks (HandlerStack) allow composable request/response modification: logging, retries, authentication headers, and caching. Guzzle is PSR-7 compliant (RequestInterface, ResponseInterface) and PSR-18 compliant (ClientInterface), making it swappable for testing. The Symfony HttpClient component is a modern alternative with tighter Symfony integration; for simpler use cases, PHP's built-in file_get_contents with stream contexts or curl_exec suffice.

Common Misconception

Guzzle is always needed for HTTP requests. For simple one-off requests, file_get_contents() with a stream context or curl_exec() is fine and requires no dependency. Use Guzzle when you need middleware, retries, async requests, or a testable/mockable interface.

Why It Matters

Almost every PHP application makes outbound HTTP requests — calling payment APIs, weather services, internal microservices, or LLM endpoints. Guzzle provides retry logic, connection pooling, middleware, and async requests that curl_exec() requires hundreds of lines to replicate. It is also the de facto standard: Laravel's HTTP facade wraps Guzzle, and most PHP SDK packages use it as their transport.

Common Mistakes

  • Not setting a timeout — without a timeout, Guzzle waits indefinitely; always set 'timeout' and 'connect_timeout'.
  • Not mocking Guzzle in tests — real HTTP calls in tests are slow and flaky; always inject a MockHandler or use a PSR-18 compatible mock.
  • Catching \Exception instead of RequestException — Guzzle throws RequestException (4xx/5xx) and ConnectException (network failure); catch them separately.
  • Creating a new Client instance per request — instantiating a Client is cheap but the underlying connection pool is per-instance; create one shared instance (singleton or DI).

Code Examples

✗ Vulnerable
<?php
// ❌ Manual curl — verbose, no retry, no error handling
$ch = curl_init('https://api.example.com/users');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $token]);
$body   = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) { /* manual error handling */ }
$data = json_decode($body, true); // Breaks silently on network error
✓ Fixed
<?php
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

// ✅ Guzzle — clean, retry-able, mockable
$client = new Client([
    'base_uri' => 'https://api.example.com',
    'timeout'  => 5.0,
    'headers'  => ['Authorization' => 'Bearer ' . $token],
]);

try {
    $response = $client->get('/users', [
        'query' => ['page' => 1, 'limit' => 50],
    ]);
    $users = json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
} catch (RequestException $e) {
    $statusCode = $e->getResponse()?->getStatusCode();
    Log::error('API call failed', ['status' => $statusCode, 'message' => $e->getMessage()]);
    throw new ApiException('Failed to fetch users', previous: $e);
}

// ✅ Retry middleware — automatic retry on 5xx and network errors
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Request;

$stack = HandlerStack::create();
$stack->push(Middleware::retry(function ($retries, Request $req, $res, $exc) {
    return $retries < 3 && ($exc !== null || $res->getStatusCode() >= 500);
}, fn($retries) => 1000 * 2 ** $retries)); // Exponential backoff

Added 23 Mar 2026
Views 19
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S
Amazonbot 1
No pings yesterday
Amazonbot 6 Perplexity 2 ChatGPT 1 Google 1 Ahrefs 1
crawler 11
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
For HTTP requests in tests, use MockHandler: $mock = new MockHandler([new Response(200, [], json_encode($data))]); $client = new Client(['handler' => HandlerStack::create($mock)]); — no real network calls needed.
📦 Applies To
PHP 7.2+ web cli laravel symfony

✓ schema.org compliant