thingston / psr18
Implementation of PSR-18 standard for sending HTTP requests and receiving HTTP responses.
Requires
- php: >=8.5
- ext-curl: *
- psr/http-client: ^1.0
- thingston/psr17: ^1.0
Requires (Dev)
- ext-xdebug: *
- friendsofphp/php-cs-fixer: ^3.89
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^13.1
Provides
This package is auto-updated.
Last update: 2026-05-17 14:41:24 UTC
README
Implementation of PSR-18 standard for sending HTTP requests and receiving HTTP responses.
Requirements
- PHP 8.5 or newer
- PHP cURL extension
Installation
composer require thingston/psr18
Usage
<?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.
Configuration
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), );
Notes
- 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.