oihana/php-middleware
Composer 安装命令:
composer require 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.
关键字:
README 文档
README
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 & conditional requests, and pagination headers — PSR-7 compatible, zero magic strings.
📚 Documentation
Full API reference (generated with phpDocumentor): https://bcommebois.github.io/oihana-php-middleware
User guides (FR + EN) live under wiki/.
📦 Installation
Requires PHP 8.4+. Install via Composer:
composer require oihana/php-middleware
✨ What you can do
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) andPermissions-Policyto a PSR-7Responsein one call. Typed values viaReferrerPolicy,FrameOptions,CrossOriginOpenerPolicy,CrossOriginEmbedderPolicy,CrossOriginResourcePolicyandPermissionsPolicyFeatureenums — no magic strings.buildCspHeader()— compose aContent-Security-Policyvalue from an associative array of directives.CspDirectiveenum exposes the canonical directive names.buildPermissionsPolicyHeader()— compose aPermissions-Policyvalue with a smart allowlist API (false,true/'*','self', single origin or array —selfstays a token, origins auto-quoted).withDefaultSecurityBaseline()— opinionated alias ofwithSecurityHeaders()shipping a "safe-for-most-apps" baseline (HSTS 1 year,X-Frame-Options: DENY, nosniff,Referrer-Policy: strict-origin-when-cross-origin, COOP / CORPsame-origin) with caller-supplied overrides merged on top.
CORS
applyCorsHeaders()— origin allowlist with configurable methods, headers, exposed headers, credentials and max-age. Handles the preflightOPTIONSrequest automatically. Defensive defaults: no*whencredentials = true,Vary: Originadded 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
generateCsrfToken()/verifyCsrfToken()— stateless signed double-submit pattern. Wire format<id>.<exp>.<sig>with a 128-bit base64url random<id>, an absolute expiry timestamp and a base64url HMAC-SHA256 signature keyed by your secret. Optional TTL. Constant-time verification — never throws on bad input, returnsbool.CsrfFieldenum ships the conventionalcookieandheadernames.
Request ID
requestIdFromRequest()— readsX-Request-Idfrom 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).RequestIdFieldenum —HEADER_NAME(X-Request-Id) andATTRIBUTE_NAME(requestId) for wiring the propagation through the middleware chain.
Maintenance mode
respondMaintenanceMode()— turns a PSR-7 response into a clean503 Service Unavailablewith optionalRetry-Afterheader (acceptsintdelta-seconds,DateTimeInterfaceformatted as IMF-fixdate, or rawstring) and optional body.MaintenanceOptionenum carries the option keys.
Rate limiting
enforceRateLimit()— fixed-window rate-limit enforcement on PSR-7 requests. Identity resolved verbatim fromKEY(string), via callablefn(Request): string, or by fallback to the client IP. Returns an immutableRateLimitDecision(allowed,limit,remaining,reset,retryAfter).withRateLimitHeaders()— stampsLimit / Remaining / Reseton the response from a decision, plusRetry-Afterwhen blocked. Defaults to the legacyX-RateLimit-*family, opt-in to the RFC 9421 draftRateLimit-*family.RateLimitStoreinterface — single atomic methodincrement(string $key, int $window): int. ShippedInMemoryRateLimitStore(process-local, for tests and CLI tools) ; production-gradeMemcachedRateLimitStoreinoihana/php-memcached.
Observability
withResponseTime()— stamps the elapsed processing time on the response. Two output formats: de-factoX-Response-Time: 42.50ms(default) or W3CServer-Timing: total;dur=42.50(opt-in viaResponseTimeOption::USE_SERVER_TIMING).
Content negotiation
negotiateMimeType()— thin PSR-7 wrapper overoihana\http\helpers\negotiation\negotiate()to select the best server-side MIME type from the clientAcceptheader. Honours RFC 7231 quality values, standard wildcards (universal andtype/*) andq=0explicit refusals.negotiateCharset()/negotiateEncoding()/negotiateLanguage()— sibling wrappers selecting the best charset, content-encoding or language from the matchingAccept-Charset/Accept-Encoding/Accept-Languagerequest header, with the same quality-value semantics.
Distributed tracing
traceContextFromRequest()/withTracingAttribute()/withTraceparentResponseHeader()/parseTraceparent()— W3C Trace Context propagation. Extract or generate atraceparent, expose theTraceContextvalue object as a request attribute, and echo the canonicaltraceparentback on the response so a single user request can be reconstructed end-to-end across services from your log aggregator.TracingFieldenum carries the wiring names.
Problem Details
respondProblemDetails()— RFC 9457 standardised error responses (application/problem+json) built from aProblemvalue object: typed standard fields (type,title,status,detail,instance) plus arbitrary extension members.ProblemFieldenum carries the field names.
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 theWebhookSignatureOptionenum.
Request defense
enforceMaxBodySize()/enforceTrustedHosts()— pre-parsing guards that reject obviously-bad requests before the application has to handle them: oversized request bodies (declaredContent-Lengthor streamed) and Host-header attacks (allowlist with wildcard-subdomain support, port stripping, fail-open on an empty allowlist).
HTTP caching & conditional requests
buildCacheControl()— compose aCache-Controlvalue from typedCacheDirectivenames (RFC 9111 / 5861 / 8246), catching themax_agevsmax-agetypo class that silently disables caching.isNotModified()/respondNotModified()— evaluate RFC 9110 conditional requests (ETag/If-None-Matchweak comparison,If-Modified-Since) and emit a canonical304 Not Modifiedresponse.
Pagination
withPaginationHeaders()— stamps the RFC 5988 / RFC 8288Linkheader (rel="first|prev|next|last") and the de-factoX-Total-Countheader from aPaginationLinksvalue object, keeping the response body pure data (GitHub-style API pagination).
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-httpprimitives (IP detection, content negotiation, etc.) andoihana/php-enumstyped HTTP constants (HttpHeader,HttpMethod,HttpStatusCode,AuthScheme, …).
✅ 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 for the full testing & coverage workflow.
🛠️ Generate the documentation
composer doc
🧾 License
Licensed under the Mozilla Public License 2.0 (MPL‑2.0).
👤 About the author
- Author: Marc ALCARAZ (aka eKameleon)
- Email:
marc@ooop.fr - Website:
https://www.ooop.fr
🔗 Related packages
| Package | Description |
|---|---|
oihana/php-http |
Composable PHP HTTP primitives (client IP detection, signed URLs, cookies, content negotiation, …) consumed by this library. |
oihana/php-enums |
Typed HTTP constants (HttpHeader, HttpMethod, HttpStatusCode, AuthScheme, …). |
oihana/php-memcached |
Production-grade MemcachedRateLimitStore implementing this package's RateLimitStore interface. |
统计信息
- 总下载量: 11
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MPL-2.0
- 更新时间: 2026-05-27
