PHPackages                             amashukov/http-client-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. amashukov/http-client-php

ActiveLibrary[HTTP &amp; Networking](/categories/http)

amashukov/http-client-php
=========================

PSR-18 HTTP client backed by ext-curl, with a middleware pipeline (retry on selected status codes, header injection). PSR-7 / PSR-17 message + factory interfaces; bring your own PSR-7 implementation (nyholm/psr7, guzzlehttp/psr7, slim/psr7, etc.).

v0.1.0(2mo ago)0350↑46.2%3MITPHPPHP &gt;=8.3CI passing

Since May 24Pushed 2mo agoCompare

[ Source](https://github.com/AndreyMashukov/http-client-php)[ Packagist](https://packagist.org/packages/amashukov/http-client-php)[ RSS](/packages/amashukov-http-client-php/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (9)Versions (2)Used By (3)

amashukov/http-client-php
=========================

[](#amashukovhttp-client-php)

Tiny zero-dependency PSR-18 HTTP client backed by ext-curl, with a retry / header-injection middleware pipeline.

[![CI](https://camo.githubusercontent.com/ed5a4e301a0abd86c86585e95fd090905a06bcb7fd55811618c0d6c529bacc89/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f416e647265794d617368756b6f762f687474702d636c69656e742d7068702f63692e796d6c3f6272616e63683d6d61696e266c6162656c3d4349)](https://github.com/AndreyMashukov/http-client-php/actions)[![PHPStan L9](https://camo.githubusercontent.com/526ec4866cd6ac9d3a029daf939d3affaf55ca52a5f8b94863d857dada0b42ad/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f416e647265794d617368756b6f762f687474702d636c69656e742d7068702f7374616e2e796d6c3f6272616e63683d6d61696e266c6162656c3d5048505374616e2532304c39)](https://github.com/AndreyMashukov/http-client-php/actions)[![Latest Version](https://camo.githubusercontent.com/e8ea449bf71db78ef868b15603d2c24e8ed4fbf899ba686be94ce896e9c899b0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616d617368756b6f762f687474702d636c69656e742d706870)](https://packagist.org/packages/amashukov/http-client-php)[![Downloads](https://camo.githubusercontent.com/729ac65ee1145a5ac841636ffc65e626e497b1f524005426dbafbcfac65f6670/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f616d617368756b6f762f687474702d636c69656e742d706870)](https://packagist.org/packages/amashukov/http-client-php)[![PHP](https://camo.githubusercontent.com/9e8300e4a214df46449eb319d8056d16389703ed011079f5d6e0bcc8cb4b034f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f616d617368756b6f762f687474702d636c69656e742d7068702f706870)](https://packagist.org/packages/amashukov/http-client-php)[![License](https://camo.githubusercontent.com/fd262ddedefb03b0c6b238cdf084fbe0ab3c7cef7c38c24d8be2e9ce51d5c93d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f616d617368756b6f762f687474702d636c69656e742d706870)](LICENSE)[![Stars](https://camo.githubusercontent.com/073774103e8e8c01b7ead8124f3c7f0cda029739248eba7fd74584ce81d5f289/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f416e647265794d617368756b6f762f687474702d636c69656e742d7068703f7374796c653d736f6369616c)](https://github.com/AndreyMashukov/http-client-php)

A small **PSR-18 HTTP client** backed by `ext-curl`, with a composable **middleware pipeline** (retry on selected status codes, header injection). It speaks PSR-7 requests + responses end-to-end and consumes PSR-17 factories, so any PSR-7 implementation (`nyholm/psr7`, `guzzlehttp/psr7`, `slim/psr7`, …) plugs in as the message layer. The package does **not** ship its own PSR-7 implementation — bring whichever you already use.

Features
--------

[](#features)

- PSR-18 `ClientInterface` over `ext-curl` — drop-in anywhere a PSR-18 client is expected.
- Composable middleware `Pipeline` (itself a PSR-18 client).
- `RetryMiddleware` — exponential backoff on configurable status codes and network errors.
- `HeaderInjectionMiddleware` — stamp API keys / `User-Agent` / telemetry headers on every request.
- Network failures surface as a PSR-18 `NetworkExceptionInterface` carrying the failed request.
- PSR-7 / PSR-17 consumed via interfaces — bring your own implementation.
- PHPStan level 9 clean, `strict_types`, `final` classes.

Why amashukov/http-client-php
-----------------------------

[](#why-amashukovhttp-client-php)

Guzzle is excellent but heavy — it pulls in `guzzlehttp/psr7`, `guzzlehttp/promises`, and its own promise/handler machinery. When all you need is a PSR-18 client that does retries and header injection, this package is a tiny, zero-runtime-dependency alternative: just `ext-curl` plus the PSR interface packages. You supply the PSR-7 implementation you already have, so there is no duplicate message library in your dependency tree.

Installation
------------

[](#installation)

```
composer require amashukov/http-client-php nyholm/psr7
```

(Substitute `nyholm/psr7` for the PSR-7 implementation of your choice.)

Usage
-----

[](#usage)

### Send a request

[](#send-a-request)

```
use Amashukov\HttpClient\CurlClient;
use Nyholm\Psr7\Factory\Psr17Factory;

$factory = new Psr17Factory();
$client  = new CurlClient($factory, $factory);

$request  = $factory->createRequest('GET', 'https://api.example.test/data');
$response = $client->sendRequest($request);

echo $response->getStatusCode();          // 200
echo (string) $response->getBody();       // raw body
```

`CurlClient` implements `Psr\Http\Client\ClientInterface`; it is a drop-in replacement anywhere a PSR-18 client is expected. The constructor takes a `Psr\Http\Message\ResponseFactoryInterface` and a `Psr\Http\Message\StreamFactoryInterface` so the caller controls which PSR-7 implementation backs the returned `ResponseInterface`.

Network failures (DNS, connect timeout, TLS handshake, …) surface as `Amashukov\HttpClient\Exception\TransportException`, which implements `Psr\Http\Client\NetworkExceptionInterface` (and therefore `ClientExceptionInterface`); `getRequest()` returns the request that failed.

### Add middlewares

[](#add-middlewares)

`Pipeline` wraps any PSR-18 client with an ordered list of middlewares, and is itself a PSR-18 client.

```
use Amashukov\HttpClient\Pipeline;
use Amashukov\HttpClient\Middleware\HeaderInjectionMiddleware;
use Amashukov\HttpClient\Middleware\RetryMiddleware;

$client = new Pipeline(
    new CurlClient($factory, $factory),
    [
        new HeaderInjectionMiddleware(['X-Api-Key' => $apiKey]),
        new RetryMiddleware(
            maxAttempts: 3,
            retryStatusCodes: [429, 502, 503, 504],
            baseDelayMs: 200,
        ),
    ],
);

$response = $client->sendRequest($request);
```

### Writing your own middleware

[](#writing-your-own-middleware)

Implement `Amashukov\HttpClient\MiddlewareInterface`:

```
use Amashukov\HttpClient\MiddlewareInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

final class LoggingMiddleware implements MiddlewareInterface
{
    public function handle(RequestInterface $request, callable $next): ResponseInterface
    {
        $start    = microtime(true);
        $response = $next($request);
        printf("%s %s -> %d (%.0fms)\n",
            $request->getMethod(),
            $request->getUri(),
            $response->getStatusCode(),
            (microtime(true) - $start) * 1000,
        );

        return $response;
    }
}
```

Call `$next($request)` exactly once for normal flow, or zero times to short-circuit with a synthetic response.

### Built-in middlewares

[](#built-in-middlewares)

**`HeaderInjectionMiddleware`** — sets the configured headers on every outbound request, replacing any caller-supplied value for the same name. Useful for API keys, `User-Agent`, telemetry headers.

**`RetryMiddleware`** — retries on configured status codes (default `[429, 502, 503, 504]`) and on any thrown `Psr\Http\Client\NetworkExceptionInterface`. Delay is exponential (`baseDelayMs * 2^(attempt-1)`); `baseDelayMs=0` means immediate retry. Returns the last response when all attempts are exhausted; rethrows the last network exception when every attempt failed at the transport layer. A `$sleeper` callable can be injected to control timing in tests.

Requirements
------------

[](#requirements)

- PHP 8.3+
- `ext-curl`
- `psr/http-client` ^1.0
- `psr/http-message` ^2.0
- `psr/http-factory` ^1.1
- A PSR-7 implementation (caller-provided)

### PSR conformance

[](#psr-conformance)

- **PSR-18** — `CurlClient` and `Pipeline` implement `Psr\Http\Client\ClientInterface`; `composer.json` declares `provide: { psr/http-client-implementation: "1.0" }`.
- **PSR-7** — every public method exchanges `Psr\Http\Message\RequestInterface` / `ResponseInterface`.
- **PSR-17** — `CurlClient` consumes `ResponseFactoryInterface` + `StreamFactoryInterface`; it does not implement those factories itself, leaving the choice of PSR-7 implementation to the caller.

Related packages
----------------

[](#related-packages)

PackageTierPurpose[amashukov/toncenter-client-php](https://github.com/AndreyMashukov/toncenter-client-php)RPCtoncenter v2/v3 API client (uses this client)[amashukov/eth-rpc-client-php](https://github.com/AndreyMashukov/eth-rpc-client-php)RPCEthereum JSON-RPC client (uses this client)[amashukov/ton-php](https://github.com/AndreyMashukov/ton-php)metaTON umbrella package[amashukov/eth-php](https://github.com/AndreyMashukov/eth-php)metaEVM umbrella packageQuality
-------

[](#quality)

- PHPStan level 9.
- php-cs-fixer with the `@PER-CS` ruleset.
- GitHub Actions CI on every push.
- PSR-18 conformance exercised in the test suite against a PSR-7 implementation.

License
-------

[](#license)

MIT.

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance88

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

62d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4b3e86ca79a82515b23e0239b1d3616c747e59b64c40e169d538d5c759c9bbc4?d=identicon)[Andrey Mashukov](/maintainers/Andrey%20Mashukov)

---

Top Contributors

[![AndreyMashukov](https://avatars.githubusercontent.com/u/24682497?v=4)](https://github.com/AndreyMashukov "AndreyMashukov (3 commits)")

---

Tags

curlhttp-clientmiddlewarephppsr-18psr-7retrypsr-7middlewarepsr-17curlhttp clientpsr-18

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/amashukov-http-client-php/health.svg)

```
[![Health](https://phpackages.com/badges/amashukov-http-client-php/health.svg)](https://phpackages.com/packages/amashukov-http-client-php)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

7.9k1.1B4.1k](/packages/guzzlehttp-psr7)[tempest/framework

The PHP framework that gets out of your way.

2.2k34.4k16](/packages/tempest-framework)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

36789.4k2](/packages/telnyx-telnyx-php)[laudis/neo4j-php-client

Neo4j-PHP-Client is the most advanced PHP Client for Neo4j

185702.8k44](/packages/laudis-neo4j-php-client)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28150.5k](/packages/phpro-http-tools)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
