Skip to content

HttpClient

Benyamin Khalife edited this page May 20, 2026 · 3 revisions

HttpClient

The HttpClient class provides a fluent, chainable API for making HTTP requests using cURL. It supports all common HTTP methods, authentication, JSON, form data, file uploads, middleware, and more.

Requires: PHP 8.0+, cURL extension enabled


Table of Contents


Installation & Basic Usage

useWebrium\HttpClient;
$response = HttpClient::make()
->get('https://api.example.com/users');
echo$response->body();

Creating an Instance

You can create an HttpClient instance in two ways:

Using the static factory (recommended):

$client = HttpClient::make();
// With a base URL$client = HttpClient::make('https://api.example.com');

Using the constructor:

$client = newHttpClient();
// With a base URL$client = newHttpClient('https://api.example.com');

When a base URL is provided, subsequent requests can use relative or absolute paths.


Making Requests

GET

$response = HttpClient::make()->get('https://api.example.com/users');
// With query parameters$response = HttpClient::make()->get('https://api.example.com/users', [
'page' => 1,
'limit' => 20,
]);

POST

$response = HttpClient::make()->post('https://api.example.com/users', $data);

PUT

$response = HttpClient::make()->put('https://api.example.com/users/1', $data);

PATCH

$response = HttpClient::make()->patch('https://api.example.com/users/1', $data);

DELETE

$response = HttpClient::make()->delete('https://api.example.com/users/1');

Request Configuration

All configuration methods return $this, so they can be chained freely.

Headers

Set multiple headers at once:

$response = HttpClient::make()
->withHeaders([
'Accept' => 'application/json',
'X-Custom-Header' => 'value',
])
->get('https://api.example.com/data');

Set a single header:

$response = HttpClient::make()
->withHeader('Accept', 'application/json')
->get('https://api.example.com/data');

Authentication

Bearer token:

$response = HttpClient::make()
->withToken('your-api-token')
->get('https://api.example.com/protected');

Basic auth:

$response = HttpClient::make()
->withBasicAuth('username', 'password')
->get('https://api.example.com/protected');

Query Parameters

$response = HttpClient::make()
->withQuery(['search' => 'webrium', 'page' => 2])
->get('https://api.example.com/posts');
// Equivalent URL: https://api.example.com/posts?search=webrium&page=2

Request Body

$response = HttpClient::make()
->withBody('raw body content')
->post('https://api.example.com/data');

Content Types

JSON request:

$response = HttpClient::make()
->asJson('POST', 'https://api.example.com/users', [
'name' => 'John Doe',
'email' => 'john@example.com',
]);

This automatically sets Content-Type: application/json and Accept: application/json.

URL-encoded form data:

$response = HttpClient::make()
->asForm('https://api.example.com/login', [
'username' => 'john',
'password' => 'secret',
]);

Multipart form data (file upload):

$response = HttpClient::make()
->asMultipart('https://api.example.com/upload', [
'file' => new \CURLFile('/path/to/file.jpg'),
'title' => 'My Photo',
]);

Timeout

$response = HttpClient::make()
->timeout(10) // 10 seconds
->get('https://api.example.com/slow-endpoint');

Default timeout is 30 seconds.

SSL Verification

// Disable SSL verification (not recommended in production)$response = HttpClient::make()
->withoutVerifying()
->get('https://self-signed.example.com');

Redirects

// Follow redirects (enabled by default, max 5)$response = HttpClient::make()
->withRedirects(true, 10)
->get('https://api.example.com/redirect');
// Disable redirect following$response = HttpClient::make()
->withRedirects(false)
->get('https://api.example.com/redirect');

User Agent

$response = HttpClient::make()
->withUserAgent('MyApp/2.0')
->get('https://api.example.com/data');

Default user agent is Webrium-HttpClient/1.0.

Custom cURL Options

For advanced use cases, you can pass raw cURL options directly:

$response = HttpClient::make()
->withOptions([
CURLOPT_INTERFACE => 'eth0',
CURLOPT_DNS_SERVERS => '8.8.8.8',
])
->get('https://api.example.com/data');

Middleware

Middleware lets you modify the cURL handle before the request is sent. This is useful for logging, adding dynamic headers, or instrumenting requests.

$response = HttpClient::make()
->middleware(function ($ch, $client) {
// $ch is the cURL handle// $client is the HttpClient instancecurl_setopt($ch, CURLOPT_VERBOSE, true);
return$ch;
})
->get('https://api.example.com/data');

Multiple middleware can be chained; they execute in the order they were added.


Working with Responses

All request methods return an HttpResponse instance.

Status Checks

$response = HttpClient::make()->get('https://api.example.com/users');
$response->ok(); // true if status is 200$response->successful(); // true if status is 2xx$response->redirect(); // true if status is 3xx$response->clientError(); // true if status is 4xx$response->serverError(); // true if status is 5xx$response->failed(); // true if status is 4xx or 5xx$response->status(); // returns the integer status code (e.g. 200)

Reading the Body

// Raw body as string$body = $response->body();
// Also works via string castingecho$response;
// Parsed as JSON (returns associative array by default)$data = $response->json();
// Parsed as JSON object$data = $response->json(false);

Response Headers

// Get a specific header$contentType = $response->header('Content-Type');
// With a default fallback$value = $response->header('X-Missing', 'default');
// Get all headers as an array$allHeaders = $response->headers();

Error Handling

Throw an exception if the request failed:

try {
$response = HttpClient::make()
->get('https://api.example.com/data')
->throw();
// Only reached if 2xx$data = $response->json();
} catch (\RuntimeException$e) {
echo$e->getMessage();
}

cURL errors (network failures, DNS errors, etc.) also throw a \RuntimeException automatically.

Callbacks

HttpClient::make()
->get('https://api.example.com/users')
->onSuccess(function ($response) {
$users = $response->json();
// handle success
})
->onError(function ($response) {
echo'Failed with status: ' . $response->status();
});

Callbacks can be chained after throw() as well.


Reusing a Client Instance

You can reuse a client with a shared base URL or shared configuration, then reset per-request state between calls:

$client = HttpClient::make('https://api.example.com')
->withToken('shared-api-token')
->withHeader('Accept', 'application/json');
$users = $client->get('/users')->json();
$client->reset(); // clears method, headers, body, query, middleware$posts = $client->get('/posts')->json();

Note:reset() does not clear the base URL or timeout — only per-request state (headers, body, query params, middleware).


API Reference

HttpClient Methods

MethodDescription
make(?string $baseUrl)Static factory to create a new instance
url(string $url)Set the request URL
withQuery(array $params)Add query string parameters
withHeaders(array $headers)Set multiple request headers
withHeader(string $key, string $value)Set a single request header
withToken(string $token)Set Bearer token authorization
withBasicAuth(string $user, string $pass)Set Basic authorization
withBody(mixed $body)Set the raw request body
timeout(int $seconds)Set request timeout in seconds
withoutVerifying()Disable SSL certificate verification
withRedirects(bool $follow, int $max)Configure redirect behavior
withUserAgent(string $userAgent)Set the User-Agent header
withOptions(array $options)Set raw cURL options
middleware(callable $callback)Add a middleware callback
get(?string $url, array $query)Send a GET request
post(?string $url, mixed $data)Send a POST request
put(?string $url, mixed $data)Send a PUT request
patch(?string $url, mixed $data)Send a PATCH request
delete(?string $url, mixed $data)Send a DELETE request
asJson(string $method, ?string $url, array $data)Send a JSON request
asForm(?string $url, array $data)Send a URL-encoded form request
asMultipart(?string $url, array $data)Send a multipart form request
reset()Reset per-request state for reuse

HttpResponse Methods

MethodReturnDescription
status()intHTTP status code
ok()boolTrue if status is 200
successful()boolTrue if status is 2xx
redirect()boolTrue if status is 3xx
clientError()boolTrue if status is 4xx
serverError()boolTrue if status is 5xx
failed()boolTrue if status is 4xx or 5xx
body()stringRaw response body
json(bool $assoc)mixedBody decoded as JSON
header(string $key, mixed $default)mixedA single response header
headers()arrayAll response headers
throw()selfThrows RuntimeException if failed
onSuccess(callable $callback)selfRuns callback if successful
onError(callable $callback)selfRuns callback if failed
info(?string $key)mixedRaw cURL info data
__toString()stringReturns the response body

Clone this wiki locally