-
Notifications
You must be signed in to change notification settings - Fork 0
PSR 18 Client
InitPHP\HTTP\Client\Client is the PSR-18 transport. It takes a Psr\Http\Message\RequestInterface and ships it over the wire via cURL, returning a Psr\Http\Message\ResponseInterface.
use InitPHP\HTTP\Client\Client;
$client = new Client();The constructor verifies ext-curl is loaded; if it isn't, you get a ClientException (PSR-18's ClientExceptionInterface).
public function sendRequest(RequestInterface $request): ResponseInterface;use InitPHP\HTTP\Message\Request;
$response = $client->sendRequest(new Request('GET', 'https://httpbin.org/uuid'));
echo $response->getStatusCode(); // 200
echo (string) $response->getBody(); // {"uuid":"..."}4xx and 5xx are not exceptions. They come back as normal responses. Only transport-level failures raise exceptions — see Client Exceptions.
For the common case where you don't want to build a full Request:
$client->get(string $url, $body = null, array $headers = [], string $version = '1.1');
$client->post(string $url, $body = null, array $headers = [], string $version = '1.1');
$client->put(string $url, $body = null, array $headers = [], string $version = '1.1');
$client->patch(string $url, $body = null, array $headers = [], string $version = '1.1');
$client->delete(string $url, $body = null, array $headers = [], string $version = '1.1');
$client->head(string $url, $body = null, array $headers = [], string $version = '1.1');Each is a one-line shortcut around prepareRequest() + sendRequest():
$response = $client->post(
'https://api.example.com/users',
json_encode(['name' => 'Ada']),
['Content-Type' => 'application/json'],
'1.1'
);$response = $client->fetch('https://api.example.com/users', [
'method' => 'POST',
'body' => $body, // string|resource|StreamInterface|null
'headers' => ['Content-Type' => 'application/json'],
'version' => '1.1',
]);Keys are case-insensitive. Both body and data aliases are accepted for the payload.
The client accepts only these body shapes:
| Type | Behaviour |
|---|---|
null |
Empty body |
string |
Sent verbatim |
resource |
Read into a Stream and sent |
StreamInterface |
Used directly |
| anything else |
InvalidArgumentException from prepareRequest()
|
This is deliberate: a PSR-18 client should not silently serialise arbitrary values — the codec choice (JSON, XML, form-encoded, ...) lives in the application, not the transport. If you want a convenience layer that auto-encodes arrays and toArray()-able objects as JSON, use the send_request() global helper — see Helpers.
v2 → v3 note: The previous client coerced
array,DOMDocument,SimpleXMLElement, and "any object" into a body. That cascade is gone. Pre-encode structured payloads before passing them in. See Migration Guide.
The returned Response carries a Stream backed by php://temp — small bodies stay in memory, larger bodies (>2 MiB by default) spill to disk transparently. Don't assume the body fits in a PHP string; for piping responses to other sinks, use getBody()->read($bufferLen) in a loop. See Recipe — Streaming Large Files.
Redirects are followed by default (cURL's CURLOPT_FOLLOWLOCATION = true, up to 10 hops). The returned response represents the final leg — status, headers, and body all come from the final URL. Intermediate responses are not exposed.
Toggle / tune:
$client = $client->withFollowRedirects(false); // disabled
$client = $client->withFollowRedirects(true, $maxRedirects = 3); // up to 3 hopsThe client maps the request's getProtocolVersion() to the matching CURL_HTTP_VERSION_* constant:
| Request version | cURL constant |
|---|---|
'1.0' |
CURL_HTTP_VERSION_1_0 |
'1.1' (default) |
CURL_HTTP_VERSION_1_1 |
'2' / '2.0'
|
CURL_HTTP_VERSION_2_0 |
HTTP/3 selection depends on your cURL build; add [CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_3] via withCurlOptions() if your binary supports it. See Configuration.
POST/PUT/PATCH/DELETE requests always set CURLOPT_POSTFIELDS, even when the body is empty. Without that, cURL silently downgrades the request to a body-less one — CUSTOMREQUEST alone is not enough. v3 handles this; v2 had a subtle bug where empty POSTs sometimes arrived at the server as GETs. See Migration Guide.
-
Configuration — timeouts, user agent, raw
CURLOPT_*overrides. - Client Exceptions — the PSR-18 error contract.
-
Helpers — the
send_request()global helper that auto-encodes arrays/objects. -
Recipe — Proxying Requests — incoming
ServerRequest→ outgoingRequest.
initphp/http · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
PSR-7 Messages
PSR-17 Factories
PSR-18 Client
Emitter (SAPI)
Static Facades
Recipes
Reference
Migration & Help