PHPackages                             haspadar/carl - 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. haspadar/carl

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

haspadar/carl
=============

Immutable object-oriented curl wrapper for PHP

v0.12.0(7mo ago)114MITPHPPHP 8.4.\*CI passing

Since Aug 18Pushed 7mo agoCompare

[ Source](https://github.com/haspadar/carl)[ Packagist](https://packagist.org/packages/haspadar/carl)[ RSS](/packages/haspadar-carl/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (10)Versions (35)Used By (0)

🧊 Carl
======

[](#-carl)

[![PHP Version](https://camo.githubusercontent.com/b37db47746bb49d291c47c3cc8fabd15219dc271ef4a998933fcd59e950d22b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342d626c7565)](https://www.php.net/releases/8.4/)[![CI](https://github.com/haspadar/carl/actions/workflows/ci.yml/badge.svg)](https://github.com/haspadar/carl/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/09a618e54fc9e6375ac242058df4b5ce504ca1549dff61efdd95c1a485021ba8/68747470733a2f2f636f6465636f762e696f2f67682f68617370616461722f6361726c2f636f7665726167652e7376673f6272616e63683d6d61696e)](https://app.codecov.io/gh/haspadar/carl)[![PHPStan Level](https://camo.githubusercontent.com/942bdbddc7b2adea1d63ed80793492d06d72ef41911edcba33310d0745581548/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d4c6576656c253230392d627269676874677265656e)](https://phpstan.org/)[![Psalm](https://camo.githubusercontent.com/8ed831918c897d26a357e18e30ccfe73b2882f59ffe3b9980abbc1b9f57257f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7073616c6d2d6c6576656c253230382d627269676874677265656e)](https://psalm.dev)[![Mutation testing badge](https://camo.githubusercontent.com/7898311e5bb415b336a6d9348f36e200b14c8ab23cb9360b03c76aa7b102e4d2/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f7374796c653d666c61742675726c3d687474707325334125324625324662616467652d6170692e737472796b65722d6d757461746f722e696f2532466769746875622e636f6d25324668617370616461722532466361726c2532466d61696e)](https://dashboard.stryker-mutator.io/reports/github.com/haspadar/carl/main)[![CodeRabbit Pull Request Reviews](https://camo.githubusercontent.com/dd55a5c8526ecfdacf2539fd14c5a0179d321d29ad22ef279552a1b112b899e1/68747470733a2f2f696d672e736869656c64732e696f2f636f64657261626269742f7072732f6769746875622f68617370616461722f6361726c3f75746d5f736f757263653d6f73732675746d5f6d656469756d3d6769746875622675746d5f63616d706169676e3d68617370616461722532466361726c266c6162656c436f6c6f723d31373137313726636f6c6f723d464635373041266c6162656c3d436f64655261626269742b52657669657773)](https://coderabbit.ai)

Immutable HTTP client for PHP built on cURL. Pure OOP, no `null`, no `static`.
Inspired by [Elegant Objects](https://www.elegantobjects.org/#principles) and [cactoos](https://github.com/yegor256/cactoos).

---

Features
--------

[](#features)

- Final, immutable classes with single responsibility
- No `null` values anywhere
- No `static` methods or state
- Lazy evaluation of HTTP requests
- Built-in fake clients and responses for testing
- No external dependencies except PHP and cURL

---

Simple Request Example
----------------------

[](#simple-request-example)

```
$response = new CurlClient()->outcome(
    new GetRequest('https://httpbin.org/get')
)->response();

echo $response->body();
```

---

Parallel Requests with onSuccess and onFailure
----------------------------------------------

[](#parallel-requests-with-onsuccess-and-onfailure)

```
$client = new CurlClient();

$requests = [
    new GetRequest('https://httpbin.org/status/200'),
    new GetRequest('https://httpbin.org/status/404'),
];

$outcomes = $client->outcomes($requests, new class implements Reaction {
    public function onSuccess(Request $request, Response $response): void
    {
        echo "Success: " . $response->body() . "\n";
    }
    public function onFailure(Request $request, string $error): void
    {
        echo "Failure: " . $error . "\n";
    }
});
+Note: CurlClient returns outcomes in completion order (not request order).
```

---

🧪 Testing with Fakes
--------------------

[](#-testing-with-fakes)

Carl provides fake classes for isolated unit testing without real HTTP calls. You can replace the real client with `FakeClient` to drive predefined outcomes.

Examples of fake outcomes:

- `AlwaysSuccessful` — always returns success (HTTP 200)
- `AlwaysFails` — always returns a failure with a given error message
- `Cycle` — cycles through a list of outcomes in order
- `FakeStatus` — returns an outcome with HTTP status code derived from the URI path

Example usage:

```
new FakeClient(new Cycle([
    new AlwaysSuccessful(new SuccessResponse("OK")),
    new AlwaysFails("network error"),
]))->outcomes(
    [
        new GetRequest('https://example.com/a'),
        new GetRequest('https://example.com/b'),
    ],
    new OnSuccessResponse(
        fn (Response $response) => print $response->body()
    )
);
// Sequence: OK, error, OK, error, ...
```

---

💤 Lazy Evaluation
-----------------

[](#-lazy-evaluation)

Carl objects are lightweight and perform no heavy work in constructors. Network I/O occurs only when you call `outcome()` or `outcomes()`. Response parsing/consumption (e.g., `body()`) is deferred until you access it. This keeps composition predictable and fast.

---

📥 Installation
--------------

[](#-installation)

```
composer require haspadar/carl
```

```
$response = new CurlClient()->outcome(
    new GetRequest('https://httpbin.org/get')
)->response();

echo $response->body();
```

### Requirements

[](#requirements)

- PHP 8.4+
- ext-curl (enabled by default in most PHP distributions)

📄 License
---------

[](#-license)

[MIT](LICENSE)

###  Health Score

36

—

LowBetter than 81% of packages

Maintenance69

Regular maintenance activity

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 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

Every ~4 days

Total

11

Last Release

214d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ec73106a22454440d5cce0b20c1aa2704983da11ba9249dd98e98bad9bb70b58?d=identicon)[haspadar](/maintainers/haspadar)

---

Top Contributors

[![haspadar](https://avatars.githubusercontent.com/u/1282194?v=4)](https://github.com/haspadar "haspadar (118 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Psalm, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/haspadar-carl/health.svg)

```
[![Health](https://phpackages.com/badges/haspadar-carl/health.svg)](https://phpackages.com/packages/haspadar-carl)
```

###  Alternatives

[friendsofsymfony/rest-bundle

This Bundle provides various tools to rapidly develop RESTful API's with Symfony

2.8k73.3M317](/packages/friendsofsymfony-rest-bundle)[php-http/discovery

Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations

1.3k309.5M1.2k](/packages/php-http-discovery)[nyholm/psr7

A fast PHP7 implementation of PSR-7

1.3k235.4M2.4k](/packages/nyholm-psr7)[pusher/pusher-php-server

Library for interacting with the Pusher REST API

1.5k94.8M292](/packages/pusher-pusher-php-server)[spatie/crawler

Crawl all internal links found on a website

2.8k16.3M52](/packages/spatie-crawler)[react/http

Event-driven, streaming HTTP client and server implementation for ReactPHP

78126.4M414](/packages/react-http)

PHPackages © 2026

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