PHPackages                             waffle-commons/http - 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. waffle-commons/http

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

waffle-commons/http
===================

Http component for Waffle framework.

0.1.0-beta4(2w ago)13842MITPHPPHP ^8.5CI passing

Since Nov 25Pushed 2w agoCompare

[ Source](https://github.com/waffle-commons/http)[ Packagist](https://packagist.org/packages/waffle-commons/http)[ RSS](/packages/waffle-commons-http/feed)WikiDiscussions main Synced today

READMEChangelog (10)Dependencies (49)Versions (26)Used By (2)

[![Discord](https://camo.githubusercontent.com/b30f41baece56d71f7f496f7e39fd33a2a096221c66c648b350dd4fe14276c2e/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3735353238383030313539323033333339313f6c6f676f3d646973636f7264)](https://discord.gg/eKgywnfXr2)[![PHP Version Require](https://camo.githubusercontent.com/8d89b06d3e92fc0e052b666a2eb184ce8bf28ae40bf417a807b0eede13c02cab/687474703a2f2f706f7365722e707567782e6f72672f776166666c652d636f6d6d6f6e732f687474702f726571756972652f706870)](https://packagist.org/packages/waffle-commons/http)[![PHP CI](https://github.com/waffle-commons/http/actions/workflows/main.yml/badge.svg)](https://github.com/waffle-commons/http/actions/workflows/main.yml)[![codecov](https://camo.githubusercontent.com/3d5c45bb94576ae0b4a04b107ddf9b0410a6ab362a9c1a25c8388754db3fa43c/68747470733a2f2f636f6465636f762e696f2f67682f776166666c652d636f6d6d6f6e732f687474702f67726170682f62616467652e7376673f746f6b656e3d64373461633632612d373837322d343033352d386238622d626363336166313939316530)](https://codecov.io/gh/waffle-commons/http)[![Latest Stable Version](https://camo.githubusercontent.com/41e59cef379d6e47804809e6a42c552e5aa7c2378eab5e27d2666cd0b14c22af/687474703a2f2f706f7365722e707567782e6f72672f776166666c652d636f6d6d6f6e732f687474702f76)](https://packagist.org/packages/waffle-commons/http)[![Latest Unstable Version](https://camo.githubusercontent.com/6da9744a1b15237d9b7593cd32f4a1cf22dd7c210215bafa5138c793b805e643/687474703a2f2f706f7365722e707567782e6f72672f776166666c652d636f6d6d6f6e732f687474702f762f756e737461626c65)](https://packagist.org/packages/waffle-commons/http)[![Total Downloads](https://camo.githubusercontent.com/f05825789dbe4dada6c3a4597527cfd3f044ce619ce896ef9b91bed22ca26784/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f776166666c652d636f6d6d6f6e732f687474702e737667)](https://packagist.org/packages/waffle-commons/http)[![Packagist License](https://camo.githubusercontent.com/7dc8fbf1d82a617703b9e2f72c1154c8aba5b6369b3e47885d005c16888775a8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f776166666c652d636f6d6d6f6e732f68747470)](https://github.com/waffle-commons/http/blob/main/LICENSE.md)

Waffle HTTP Component
=====================

[](#waffle-http-component)

> **Release:** `0.1.0-beta4` | [`CHANGELOG.md`](./CHANGELOG.md)**PSR Compliance:** PSR-7 (HTTP Messages), PSR-17 (HTTP Factories)

A strict, immutable PSR-7/17 implementation tuned for FrankenPHP worker mode. No singletons, no superglobal touching outside the explicit `GlobalsFactory`. Streams are seekable-aware; the `ResponseEmitter` chunks bodies to avoid loading large payloads into memory.

📦 Installation
--------------

[](#-installation)

```
composer require waffle-commons/http
```

🧱 Surface
---------

[](#-surface)

ClassPSRRole`Waffle\Commons\Http\Request`PSR-7Outbound HTTP request message.`Waffle\Commons\Http\ServerRequest`PSR-7Inbound HTTP request (the kernel input).`Waffle\Commons\Http\Response`PSR-7HTTP response message.`Waffle\Commons\Http\Stream`PSR-7Resource-backed `StreamInterface`.`Waffle\Commons\Http\Uri`PSR-7Immutable URI.`Waffle\Commons\Http\UploadedFile`PSR-7File-upload representation.`Waffle\Commons\Http\Abstract\AbstractMessage`—Shared base for `Request` / `ServerRequest` / `Response`.`Waffle\Commons\Http\Factory\RequestFactory`PSR-17`createRequest()`.`Waffle\Commons\Http\Factory\ServerRequestFactory`PSR-17`createServerRequest()`.`Waffle\Commons\Http\Factory\ResponseFactory`PSR-17`createResponse()`.`Waffle\Commons\Http\Factory\StreamFactory`PSR-17`createStream()`, `createStreamFromFile()`, `createStreamFromResource()`.`Waffle\Commons\Http\Factory\UriFactory`PSR-17`createUri()`.`Waffle\Commons\Http\Factory\UploadedFileFactory`PSR-17`createUploadedFile()`.`Waffle\Commons\Http\Factory\GlobalsFactory`—Implements `GlobalsFactoryInterface`: builds a PSR-7 `ServerRequest` from `$_SERVER`, `$_GET`, `$_POST`, `$_COOKIE`, `$_FILES`, and `php://input`.`Waffle\Commons\Http\Emitter\ResponseEmitter`—Implements `ResponseEmitterInterface`: sends status line, headers and chunked body.🚀 Bootstrap a server request
----------------------------

[](#-bootstrap-a-server-request)

```
use Waffle\Commons\Http\Factory\GlobalsFactory;

$factory = new GlobalsFactory();
$request = $factory->createFromGlobals(); // PSR-7 ServerRequestInterface
```

The factory takes an optional `(callable(): StreamInterface) $bodyStreamFactory` so tests can inject a synthetic body without touching `php://input`:

```
public function __construct(?callable $bodyStreamFactory = null)
```

> **Security note.** `GlobalsFactory` does **not** enforce trusted hosts. Host-header anti-poisoning is handled one layer up by `Waffle\Commons\Pipeline\Middleware\TrustedHostMiddleware`, which sits between `ErrorHandlerMiddleware` and `CoreRoutingMiddleware` in the PSR-15 stack.

📤 Emit a response
-----------------

[](#-emit-a-response)

```
use Waffle\Commons\Http\Emitter\ResponseEmitter;
use Waffle\Commons\Http\Factory\ResponseFactory;

$response = (new ResponseFactory())
    ->createResponse(200)
    ->withHeader('Content-Type', 'application/json');

(new ResponseEmitter())->emit($response);
```

The emitter:

- Throws `\RuntimeException` if headers are already sent.
- Sends one `header()` per header value (combining for non-`Set-Cookie` headers).
- Reads the response body in 8 KiB chunks via `StreamInterface::read()`, so streaming large payloads is memory-bounded.

🐘 PHP 8.5 features used
-----------------------

[](#-php-85-features-used)

- **Immutable, named-argument-friendly factories** — every `with…()` accessor returns a clone.
- **Typed properties + constructor promotion** across messages.
- **Strict types** in every file (`declare(strict_types=1);`).
- The `ResponseEmitter::emit()` signature uses `#[\Override]` to assert the contract.

🧭 Architectural boundary (`mago guard`)
---------------------------------------

[](#-architectural-boundary-mago-guard)

An active dependency **perimeter** is enforced on every CI run by `vendor/bin/mago guard` (bundled into `composer mago`; zero baselines). The rules live in [`mago.toml`](./mago.toml) under `[guard.perimeter]` — a forbidden `use` statement fails the build, not a reviewer.

Production code under `Waffle\Commons\Http` may depend **only** on:

- `Waffle\Commons\Http\**` — itself
- `Waffle\Commons\Contracts\**` — the shared contracts package, the **only** Waffle dependency permitted
- `Psr\**` — PSR interfaces (PSR-7 / PSR-17)
- `@global` + `Psl\**` — PHP core and the PHP Standard Library

Test code under `WaffleTests\Commons\Http` is unrestricted (`@all`); the `php-mock` bootstrap fixtures noted under Testing are listed in `[guard].excludes` because they intentionally re-declare the production namespace. Structural rules are guarded too: interfaces must be named `*Interface`, `Exception\**` classes must end in `*Exception`, and any `Enum\**` namespace may hold only `enum` declarations.

Contract-first, component-agnostic by construction: components compose through `waffle-commons/contracts`, never directly through one another.

🧪 Testing
---------

[](#-testing)

```
docker exec -w /waffle-commons/http waffle-dev composer tests
```

Mock-bootstrap files under `tests/src/StreamTest.php`, `tests/src/UploadedFileTest.php`, `tests/src/Factory/StreamFactoryTest.php`, and `tests/src/Emitter/ResponseEmitterTest.php` intentionally declare the production namespace to override built-in PHP functions via `php-mock-phpunit`. They are listed in `mago.toml [guard].excludes` for that reason.

📄 License
---------

[](#-license)

MIT — see [LICENSE.md](./LICENSE.md).

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance96

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity49

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 ~22 days

Recently: every ~5 days

Total

10

Last Release

19d ago

PHP version history (2 changes)0.1.0-alpha1PHP ^8.4

0.1.0-alpha4PHP ^8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/34a7557a3fb23aaf788ca3892b9b7efdf96e753264bafd0599153c9e8a921316?d=identicon)[LesliePetrimaux](/maintainers/LesliePetrimaux)

---

Top Contributors

[![supa-chayajin](https://avatars.githubusercontent.com/u/695448?v=4)](https://github.com/supa-chayajin "supa-chayajin (91 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/waffle-commons-http/health.svg)

```
[![Health](https://phpackages.com/badges/waffle-commons-http/health.svg)](https://phpackages.com/packages/waffle-commons-http)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

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

The PHP framework that gets out of your way.

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

PHP ETL - Extract Transform Load - Data processing framework

85036.3k](/packages/flow-php-flow)[laudis/neo4j-php-client

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

185702.8k44](/packages/laudis-neo4j-php-client)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.6M574](/packages/shopware-core)[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)
