Implementation of PSR-18 standard for sending HTTP requests and receiving HTTP responses.
- PHP 8.5 or newer
- PHP cURL extension
composer require thingston/psr18<?php
use Thingston\Psr17\RequestFactory;
use Thingston\Psr18\Client;
use Thingston\Psr18\Curl\RequestOptions;
use Thingston\Psr18\Curl\ResponseOptions;
use Thingston\Psr18\RetryPolicy;
$request = (new RequestFactory())
->createRequest('POST', 'https://example.com/api')
->withHeader('Accept', 'application/json');
$client = new Client(
requestOptions: (new RequestOptions())
->withOption(RequestOptions::TIMEOUT, 10)
->withOption(RequestOptions::USER_AGENT, 'thingston/http-client'),
responseOptions: (new ResponseOptions())
->withOption(ResponseOptions::ENCODING, ''),
retryPolicy: new RetryPolicy(maxRetries: 2, delayMilliseconds: 100),
);
$response = $client->sendRequest($request);The client uses the PHP cURL extension and accepts native cURL options for request and response handling. Internally, request and response options are modeled separately so defaults, validation, and client-managed options stay explicit. Options that are required to build PSR-18 compliant requests and responses, such as CURLOPT_URL, CURLOPT_HTTPHEADER, CURLOPT_WRITEFUNCTION, and CURLOPT_HEADERFUNCTION, are reserved and cannot be overridden.
Common request options are exposed as public constants for readability:
use Thingston\Psr18\Client;
use Thingston\Psr18\Curl\RequestOptions;
$client = new Client(
requestOptions: (new RequestOptions())
->withOption(RequestOptions::USER_AGENT, 'thingston/http-client')
->withOption(RequestOptions::CONNECT_TIMEOUT, 10)
->withOption(RequestOptions::MAX_REDIRECTS, 10)
->withOption(RequestOptions::FOLLOW_LOCATION, true),
);Response handling options can be configured separately:
use Thingston\Psr18\Client;
use Thingston\Psr18\Curl\ResponseOptions;
$client = new Client(
responseOptions: (new ResponseOptions())
->withOption(ResponseOptions::ENCODING, ''),
);Retry support is opt-in and retries only idempotent methods by default (GET, HEAD, OPTIONS, PUT, DELETE, TRACE). The default transient failure policy retries network-level cURL errors plus HTTP 408, 425, 429, 500, 502, 503, and 504 responses:
use Thingston\Psr18\Client;
use Thingston\Psr18\RetryPolicy;
$client = new Client(
retryPolicy: new RetryPolicy(maxRetries: 3, delayMilliseconds: 200),
);- The request URI must be absolute and include a host.
- The client supports HTTP/1.0, HTTP/1.1, HTTP/2, and HTTP/3 when the installed cURL build supports it.
- Request and response option bags reject cURL options that the client manages internally to preserve PSR-18 behavior.