kambo/httpmessage
kambo/httpmessage is a PHP package for working with HTTP messages in an object-oriented way. It helps you build, inspect, and manipulate requests, responses, headers, and bodies consistently, making HTTP handling cleaner and easier to reuse across applications.
What this package is. kambo/httpmessage is a standalone implementation of PSR-7 (psr/http-message), the FIG standard defining immutable value objects for HTTP requests, responses, URIs, streams, and uploaded files. It is a library, not a framework extension: no service provider, no facade, no config. In a Laravel codebase it can only ever occupy the HTTP boundary — it does not replace Illuminate\Http\Request/Response or Symfony HttpFoundation, which is what the framework's routing, validation, session, and middleware stack actually operate on.
Architecture fit: narrow and optional. Laravel is not a PSR-7 application. PSR-7 enters a Laravel codebase through exactly four doors:
| Door | Relevance to this package |
|---|---|
| PSR-15 middleware / third-party HTTP middleware | Would need a PSR-7 impl to marshal into |
| PSR-18 HTTP clients (e.g. third-party SDKs) | Client supplies its own messages; PSR-7 impl not needed |
symfony/psr-http-message-bridge (converting HttpFoundation ⇄ PSR-7) |
Bridge needs a factory, not arbitrary impls |
Libraries typed against Psr\Http\Message\* interfaces |
Any conformant impl satisfies the type hint |
The critical architectural point: PSR-7 consumers are typed against interfaces, so implementations are interchangeable by design. That makes this a commodity dependency with zero differentiation — the only selection criteria are conformance, maintenance, and compatibility. On all three, this package is weak.
Integration feasibility: mechanically trivial, compatibility-gated. composer require kambo/httpmessage and it works, if and only if its declared psr/http-message constraint resolves against what the rest of the tree wants. That is the whole risk surface, and it is a real one.
Technical risk (ranked):
psr/http-message 2.0 incompatibility — high likelihood, blocking. PSR-7 v1.x (2015) had no return types; v2.0 (2023) added them, and implementations must match exactly or PHP throws a fatal signature error. A package last released 2018-01-24 almost certainly pins ^1.0 only. Modern consumers (guzzlehttp/psr7 2.x, nyholm/psr7 1.x, most PSR-18 clients) require ^1.1 || ^2.0 or ^2.0, so Composer will either refuse to install or pin your entire HTTP layer to v1. Under PHP 8.x, if the resolver does allow a mix, you get a class-loading fatal. This is the single question that decides the evaluation.http-factory, 2018–2019) is how modern code creates PSR-7 objects without hard-coding a concrete class, and it's what symfony/psr-http-message-bridge and PSR-18 clients consume. A 2018 implementation predates or predates-final of this; expect to write and maintain your own factory adapter — which erodes the entire reason to use a batteries-free package.Key questions to resolve before any code is written:
psr/http-message constraint in composer.json, and does it resolve alongside our current guzzlehttp/psr7 / HTTP client versions on our target PHP (8.2/8.3)?php constraints and pass its own test suite on PHP 8.x? Is there a phpunit.xml and CI config at all?nyholm/psr7 or guzzlehttp/psr7 — both already likely present transitively)?Stack fit. Poor-to-conditional. Laravel's request lifecycle never touches PSR-7; adding this package inserts a translation layer (HttpFoundation → PSR-7 → PSR-15 → back) that buys nothing unless a concrete downstream dependency demands it. Recommended default: do not adopt; use nyholm/psr7 (minimal, actively maintained, PSR-17 factories included) plus symfony/psr-http-message-bridge if a bridge is genuinely needed. Both are already in most Laravel dependency trees, so the marginal cost is ~zero and the risk delta is large.
If adoption is mandated (e.g. licensing, an internal standard, or an air-gapped constraint), the migration path is:
Kambo\HttpMessage\* concrete classes appear in application or domain code. Type-hint only Psr\Http\Message\* interfaces, and resolve instances through an internal HttpMessageFactory interface we own. Swapping implementations then becomes a one-file change plus a container binding — hours, not weeks."kambo/httpmessage": "x.y.z"), committed composer.lock, and a conflict entry if it forces psr/http-message below what other dependencies need.HttpFoundation. Budget ~3–5 engineer-days for the adapter + tests, plus ongoing ownership.Compatibility matrix to validate in a spike (≤1 day):
| Check | Pass criteria |
|---|---|
composer why-not kambo/httpmessage on current lock |
No conflicts |
psr/http-message version installed |
Matches package constraint exactly |
| PHP 8.2/8.3 class-load smoke test | No fatal signature errors |
| Round-trip: HttpFoundation → PSR-7 → HttpFoundation | Headers, cookies, streams, uploaded files preserved |
PSR-7 conformance suite (php-http/psr7-integration-tests) |
Green, or documented exceptions |
Sequencing:
psr/http-message constraint is ^1.0-only and our tree needs ^2.0, the evaluation ends here — no further work is justified.composer audit, document the unmaintained dependency in the risk register with a named owner.nyholm/psr7, which the internal factory interface makes cheap.Maintenance: the dominant cost, and it is ours. An unmaintained dependency doesn't mean "no maintenance" — it means we are the maintainer, without the upstream's tests or intent. Realistic ongoing load: security-review exceptions every audit cycle, a manual patch path (composer patch/fork) if a bug lands, and periodic re-validation whenever PHP or psr/http-message moves. Compare against a maintained alternative where this load is near-zero. This is the clearest TPM-level argument against adoption: it converts a solved, commoditized problem into a bespoke ownership liability for no functional gain.
Support. No upstream issue response, no CVE feed participation, no vendor to escalate to. Internal engineers will not find this package in their prior experience; every question routes to whoever owns the adapter. If that person leaves, the knowledge leaves.
Scaling. Performance is not the concern — PSR-7 objects are lightweight and this implementation is unlikely to be a bottleneck versus Laravel's own request handling. The concern is scaling the team: each new engineer must learn a bespoke, undocumented HTTP message layer that exists nowhere else in their career. Onboarding cost is real and recurring; it does not amortize the way a well-known package does.
Failure modes (and blast radius):
| Failure | Trigger | Blast radius | Detection |
|---|---|---|---|
| Fatal signature error | Dependency update pulls psr/http-message 2.x |
Total app failure at boot | Deploy-time; caught by CI smoke test |
| Silent incompatibility | Mixed v1/v2 in tree under PHP 8 | Intermittent class-load fatals | Hard to reproduce; production incidents |
| Header/URI parsing bug | Malformed input from untrusted client | Injection or request-smuggling class of bugs | Not detected without adversarial testing |
| Stream memory exhaustion | Large uploads / unbounded bodies | Worker OOM, 502s | Monitoring; post-hoc |
| Dependency deadlock | Another package needs psr/http-message ^2.0 |
Cannot upgrade that package until we drop this one | Composer resolve time — visible, but blocks unrelated work |
| Unpatched CVE | Disclosure, no upstream | Indefinite exposure | Only via composer audit flagging it forever |
The deadlock row is the one that bites teams months later: a single low-value package can veto an entire ecosystem upgrade, converting a decision made today into a blocker owned by someone who never saw the original justification.
Ramp-up. Low to install, moderate to operate correctly. Any engineer can call composer require. Operating it safely requires understanding PSR-7 immutability semantics (every with* returns a clone — a common source of silent no-op bugs), stream pointer/rewind behavior, and the HttpFoundation bridge's lossy spots (cookies, uploaded file metadata, non-rewindable body streams). Budget a short internal note documenting the factory contract and the immutability gotcha; without it, expect subtle bugs where a mutated request is silently discarded.
Recommendation. Do not adopt for a Laravel codebase on current PHP. The category is fully commoditized, two actively maintained implementations are already in most dependency trees, and this package's release date puts it on the wrong side of the psr/http-message 2.0 split — the single most expensive compatibility break to inherit. If a PSR-7 boundary is genuinely required, nyholm/psr7 + symfony/psr-http-message-bridge delivers the same interface-level fit with none of the ownership burden. If adoption is nonetheless mandated, contain it behind an internal factory interface from day one and write the exit trigger into the decision record before the first commit.
How can I help you explore Laravel packages today?