PHPackages                             oihana/php-middleware - 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. oihana/php-middleware

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

oihana/php-middleware
=====================

Composable PHP middleware helpers — security headers (HSTS, CSP, X-Frame-Options, Referrer-Policy, X-Content-Type-Options), CORS with preflight, CSRF, request-id, maintenance mode, rate limiting. PSR-7 compatible, zero magic strings.

0.7.1(1mo ago)0281MPL-2.0PHPPHP &gt;=8.4CI passing

Since May 27Pushed 1mo agoCompare

[ Source](https://github.com/BcommeBois/oihana-php-middleware)[ Packagist](https://packagist.org/packages/oihana/php-middleware)[ Docs](https://github.com/BcommeBois/oihana-php-middleware)[ RSS](/packages/oihana-php-middleware/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (14)Versions (9)Used By (1)

Oihana PHP Middleware
=====================

[](#oihana-php-middleware)

[![Oihana PHP Middleware](https://raw.githubusercontent.com/BcommeBois/oihana-php-middleware/main/assets/images/oihana-php-middleware-logo-inline-512x160.png)](https://raw.githubusercontent.com/BcommeBois/oihana-php-middleware/main/assets/images/oihana-php-middleware-logo-inline-512x160.png)

Composable PHP HTTP middleware helpers.

Part of the **Oihana PHP** ecosystem, this package ships procedural helpers for HTTP security headers, CORS, CSRF, request-id propagation, maintenance mode, fixed-window rate limiting, observability, content negotiation, distributed tracing (W3C Trace Context), RFC 9457 Problem Details, webhook signature verification, request-defense guards, HTTP caching &amp; conditional requests, and pagination headers — PSR-7 compatible, zero magic strings.

[![Latest Version](https://camo.githubusercontent.com/fd433d2578b88ea85019607b566a571a95ac76b2541280894683abda93ca4216/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f6968616e612f7068702d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/oihana/php-middleware)[![Total Downloads](https://camo.githubusercontent.com/c2c2cd8c7eee74a69b94bdb85b7a086c66e2a7b1e8b605dfe8706a2b486a6cde/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6f6968616e612f7068702d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/oihana/php-middleware)[![License](https://camo.githubusercontent.com/e6640d4b27c87296e4d25c0518d79ecf2a5080f8a04e7045275072c39464e5b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6f6968616e612f7068702d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](LICENSE)

📚 Documentation
---------------

[](#-documentation)

Full API reference (generated with phpDocumentor): `https://bcommebois.github.io/oihana-php-middleware`

User guides (FR + EN) live under [`wiki/`](wiki/).

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

[](#-installation)

Requires [PHP 8.4+](https://php.net/releases/). Install via [Composer](https://getcomposer.org/):

```
composer require oihana/php-middleware
```

✨ What you can do
-----------------

[](#-what-you-can-do)

### Security headers

[](#security-headers)

- **`withSecurityHeaders()`** — single helper to apply HSTS, `Content-Security-Policy`, `X-Frame-Options`, `Referrer-Policy`, `X-Content-Type-Options`, the three Cross-Origin policies (COOP / COEP / CORP) and `Permissions-Policy` to a PSR-7 `Response` in one call. Typed values via `ReferrerPolicy`, `FrameOptions`, `CrossOriginOpenerPolicy`, `CrossOriginEmbedderPolicy`, `CrossOriginResourcePolicy` and `PermissionsPolicyFeature` enums — no magic strings.
- **`buildCspHeader()`** — compose a `Content-Security-Policy` value from an associative array of directives. `CspDirective` enum exposes the canonical directive names.
- **`buildPermissionsPolicyHeader()`** — compose a `Permissions-Policy` value with a smart allowlist API (`false`, `true` / `'*'`, `'self'`, single origin or array — `self` stays a token, origins auto-quoted).
- **`withDefaultSecurityBaseline()`** — opinionated alias of `withSecurityHeaders()` shipping a "safe-for-most-apps" baseline (HSTS 1 year, `X-Frame-Options: DENY`, nosniff, `Referrer-Policy: strict-origin-when-cross-origin`, COOP / CORP `same-origin`) with caller-supplied overrides merged on top.

### CORS

[](#cors)

- **`applyCorsHeaders()`** — origin allowlist with configurable methods, headers, exposed headers, credentials and max-age. Handles the preflight `OPTIONS` request automatically. Defensive defaults: no `*` when `credentials = true`, `Vary: Origin` added when the allowlist is dynamic.
- **`isCorsRequest()`** / **`isCorsPreflight()`** — pure predicates so middlewares can short-circuit on same-origin requests or detect a preflight without spelling out the underlying header names.

### CSRF

[](#csrf)

- **`generateCsrfToken()`** / **`verifyCsrfToken()`** — stateless signed double-submit pattern. Wire format `..` with a 128-bit base64url random ``, an absolute expiry timestamp and a base64url HMAC-SHA256 signature keyed by your secret. Optional TTL. Constant-time verification — never throws on bad input, returns `bool`. `CsrfField` enum ships the conventional `cookie` and `header` names.

### Request ID

[](#request-id)

- **`requestIdFromRequest()`** — reads `X-Request-Id` from the incoming request and returns it when it passes a conservative shape check (1 to 128 chars, URL-safe alphabet), otherwise generates a fresh 128-bit base64url identifier. Defense-in-depth against log-pollution attacks via a forged incoming header.
- **`withRequestIdHeader()`** — stamps the request ID on the response (PSR-7 immutable).
- **`RequestIdField`** enum — `HEADER_NAME` (`X-Request-Id`) and `ATTRIBUTE_NAME` (`requestId`) for wiring the propagation through the middleware chain.

### Maintenance mode

[](#maintenance-mode)

- **`respondMaintenanceMode()`** — turns a PSR-7 response into a clean `503 Service Unavailable` with optional `Retry-After` header (accepts `int` delta-seconds, `DateTimeInterface` formatted as IMF-fixdate, or raw `string`) and optional body. `MaintenanceOption` enum carries the option keys.

### Rate limiting

[](#rate-limiting)

- **`enforceRateLimit()`** — fixed-window rate-limit enforcement on PSR-7 requests. Identity resolved verbatim from `KEY` (string), via callable `fn(Request): string`, or by fallback to the client IP. Returns an immutable `RateLimitDecision` (`allowed`, `limit`, `remaining`, `reset`, `retryAfter`).
- **`withRateLimitHeaders()`** — stamps `Limit / Remaining / Reset` on the response from a decision, plus `Retry-After` when blocked. Defaults to the legacy `X-RateLimit-*` family, opt-in to the RFC 9421 draft `RateLimit-*` family.
- **`RateLimitStore`** interface — single atomic method `increment(string $key, int $window): int`. Shipped `InMemoryRateLimitStore` (process-local, for tests and CLI tools) ; production-grade `MemcachedRateLimitStore` in [`oihana/php-memcached`](https://github.com/BcommeBois/oihana-php-memcached).

### Observability

[](#observability)

- **`withResponseTime()`** — stamps the elapsed processing time on the response. Two output formats: de-facto `X-Response-Time: 42.50ms` (default) or W3C `Server-Timing: total;dur=42.50` (opt-in via `ResponseTimeOption::USE_SERVER_TIMING`).

### Content negotiation

[](#content-negotiation)

- **`negotiateMimeType()`** — thin PSR-7 wrapper over `oihana\http\helpers\negotiation\negotiate()` to select the best server-side MIME type from the client `Accept` header. Honours RFC 7231 quality values, standard wildcards (universal and `type/*`) and `q=0` explicit refusals.
- **`negotiateCharset()`** / **`negotiateEncoding()`** / **`negotiateLanguage()`** — sibling wrappers selecting the best charset, content-encoding or language from the matching `Accept-Charset` / `Accept-Encoding` / `Accept-Language` request header, with the same quality-value semantics.

### Distributed tracing

[](#distributed-tracing)

- **`traceContextFromRequest()`** / **`withTracingAttribute()`** / **`withTraceparentResponseHeader()`** / **`parseTraceparent()`** — W3C Trace Context propagation. Extract or generate a `traceparent`, expose the `TraceContext` value object as a request attribute, and echo the canonical `traceparent` back on the response so a single user request can be reconstructed end-to-end across services from your log aggregator. `TracingField` enum carries the wiring names.

### Problem Details

[](#problem-details)

- **`respondProblemDetails()`** — RFC 9457 standardised error responses (`application/problem+json`) built from a `Problem` value object: typed standard fields (`type`, `title`, `status`, `detail`, `instance`) plus arbitrary extension members. `ProblemField` enum carries the field names.

### Webhook signature verification

[](#webhook-signature-verification)

- **`verifyWebhookSignature()`** — verifies the simple-HMAC signature pattern shared by GitHub, Slack, Shopify, Twilio and SendGrid. Constant-time comparison, configurable algorithm / header prefix / encoding via the `WebhookSignatureOption` enum.

### Request defense

[](#request-defense)

- **`enforceMaxBodySize()`** / **`enforceTrustedHosts()`** — pre-parsing guards that reject obviously-bad requests before the application has to handle them: oversized request bodies (declared `Content-Length` or streamed) and Host-header attacks (allowlist with wildcard-subdomain support, port stripping, fail-open on an empty allowlist).

### HTTP caching &amp; conditional requests

[](#http-caching--conditional-requests)

- **`buildCacheControl()`** — compose a `Cache-Control` value from typed `CacheDirective` names (RFC 9111 / 5861 / 8246), catching the `max_age` vs `max-age` typo class that silently disables caching.
- **`isNotModified()`** / **`respondNotModified()`** — evaluate RFC 9110 conditional requests (`ETag` / `If-None-Match` weak comparison, `If-Modified-Since`) and emit a canonical `304 Not Modified` response.

### Pagination

[](#pagination)

- **`withPaginationHeaders()`** — stamps the RFC 5988 / RFC 8288 `Link` header (`rel="first|prev|next|last"`) and the de-facto `X-Total-Count` header from a `PaginationLinks` value object, keeping the response body pure data (GitHub-style API pagination).

### Under the hood

[](#under-the-hood)

- Pure PSR-7 — no framework lock-in. Works with Slim, Laravel, Symfony HTTP Foundation (via PSR-7 bridge), Hyperf, RoadRunner, etc.
- Built on `oihana/php-http` primitives (IP detection, content negotiation, etc.) and `oihana/php-enums` typed HTTP constants (`HttpHeader`, `HttpMethod`, `HttpStatusCode`, `AuthScheme`, …).

✅ Running tests
---------------

[](#-running-tests)

Run all tests:

```
composer test
```

Measure coverage (requires Xdebug or PCOV):

```
composer coverage      # text + Clover + HTML under build/coverage/
composer coverage:md   # readable Markdown summary (build/coverage/COVERAGE.md)
```

See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full testing &amp; coverage workflow.

🛠️ Generate the documentation
-----------------------------

[](#️-generate-the-documentation)

```
composer doc
```

🧾 License
---------

[](#-license)

Licensed under the [Mozilla Public License 2.0 (MPL‑2.0)](https://www.mozilla.org/en-US/MPL/2.0/).

👤 About the author
------------------

[](#-about-the-author)

- Author: Marc ALCARAZ (aka eKameleon)
- Email: `marc@ooop.fr`
- Website: `https://www.ooop.fr`

🔗 Related packages
------------------

[](#-related-packages)

PackageDescription[`oihana/php-http`](https://github.com/BcommeBois/oihana-php-http)Composable PHP HTTP primitives (client IP detection, signed URLs, cookies, content negotiation, …) consumed by this library.[`oihana/php-enums`](https://github.com/BcommeBois/oihana-php-enums)Typed HTTP constants (`HttpHeader`, `HttpMethod`, `HttpStatusCode`, `AuthScheme`, …).[`oihana/php-memcached`](https://github.com/BcommeBois/oihana-php-memcached)Production-grade `MemcachedRateLimitStore` implementing this package's `RateLimitStore` interface.

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance92

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

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

Total

8

Last Release

41d ago

### Community

Maintainers

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

---

Top Contributors

[![ekameleon](https://avatars.githubusercontent.com/u/749032?v=4)](https://github.com/ekameleon "ekameleon (34 commits)")

---

Tags

httppsr-7phpmiddlewaresecuritycorscsprate limitmaintenancecsrfrate limitinghstssecurity-headersrequest id

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/oihana-php-middleware/health.svg)

```
[![Health](https://phpackages.com/badges/oihana-php-middleware/health.svg)](https://phpackages.com/packages/oihana-php-middleware)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

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

PSR-15 Middleware Microframework

3923.8M126](/packages/mezzio-mezzio)[mezzio/mezzio-authentication-oauth2

OAuth2 (server) authentication middleware for Mezzio and PSR-7 applications.

28591.3k3](/packages/mezzio-mezzio-authentication-oauth2)[sunrise/http-router

A powerful solution as the foundation of your project.

17451.8k11](/packages/sunrise-http-router)[middlewares/cors

Middleware to implement Cross-Origin Resource Sharing (CORS)

1375.0k3](/packages/middlewares-cors)[mimmi20/browser-detector

Library to detect Browsers and Devices

48157.6k5](/packages/mimmi20-browser-detector)

PHPackages © 2026

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