philharmony / http-enum
Type-safe HTTP enums for methods, status codes, headers, content types, schemes, caching and protocol utilities
Requires
- php: ^8.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10.0
README
Type-safe HTTP enums for PHP: methods, status codes, headers, content types, schemes and protocol utilities โ designed for modern applications and libraries.
๐ Description
philharmony/http-enum provides a set of strictly typed, PSR-compliant enums for common HTTP concepts:
HttpMethodโ standard HTTP request methodsStatusCodeโ HTTP status codes with semantic groupingContentTypeโ common media types for responses and requestsSchemeโ URI schemes with default port mapping (RFC 3986 compliant)HttpHeaderโ common HTTP headers with semantic grouping and utilitiesAuthSchemeโ HTTP authentication schemes (Basic, Bearer, Digest, OAuth, etc.)HttpVersionโ HTTP protocol versions with parsing utilitiesCacheDirectiveโ Cache-Control directives for HTTP caching behaviorContentEncodingโ HTTP compression algorithms (gzip, br, deflate, etc.)SameSiteโ cookie SameSite policies for cross-site request protection
Built for clean, expressive, and safe code, this lightweight library requires PHP 8.1+ and has zero runtime dependencies.
It is ideal for frameworks, middleware, SDKs, and reusable components.
๐ Included Enums
HttpMethodStatusCodeContentTypeSchemeHttpHeaderAuthSchemeHttpVersionCacheDirectiveContentEncodingSameSite
โจ Why Use This Library?
Working with HTTP often involves raw strings and magic numbers:
if ($method === 'POST') { ... } if ($status >= 400) { ... } if ($header === 'Content-Type') { ... }
This library replaces them with type-safe enums:
if ($method === HttpMethod::POST) { ... } if ($status->isError()) { ... } if ($header === HttpHeader::CONTENT_TYPE) { ... }
Benefits:
- โ Type safety โ eliminates invalid values
- โ Better IDE autocompletion
- โ Self-documenting code
- โ RFC-aligned semantics
- โ Zero runtime dependencies
๐ Features
- ๐งฉ 10 HTTP enums
- โก Zero dependencies
- ๐งฌ Strict typing
- ๐ Framework agnostic
- ๐ง Semantic helper methods
- ๐ RFC-aligned behavior
- โ Fully tested
- ๐งฐ Developer-friendly utilities
๐ฆ Installation
Install via Composer:
composer require philharmony/http-enum
โ๏ธ Requirements
- PHP 8.1 or higher
๐ Usage
HTTP Methods
use Philharmony\Http\Enum\HttpMethod; $method = HttpMethod::POST; if ($method->isSafe()) { /* Handle GET, HEAD... */ } if ($method->isIdempotent()) { /* Handle PUT, DELETE... */ } if ($method->isCacheable()) { /* Handle GET, HEAD */ } if ($method->isReadOnly()) { /* Handle GET, HEAD, OPTIONS, TRACE */ } if ($method->isWriteOnly()) { /* Handle POST, PUT, PATCH, DELETE, CONNECT */ } if ($method->usuallyHasBody()) { /* POST, PUT, PATCH -> true, other false */ } if ($method->allowsBody()) { /* POST, PUT, PATCH, DELETE -> true, other false */ }
Status Codes
use Philharmony\Http\Enum\StatusCode; $status = StatusCode::NOT_FOUND; if ($status->isInformational()) { /* 1xx */ } if ($status->isSuccess()) { /* 2xx */ } if ($status->isRedirection()) { /* 3xx */ } if ($status->isClientError()) { /* 4xx */ } if ($status->isServerError()) { /* 5xx */ } if ($status->isError()) { /* 4xx and 5xx */ } if ($status->isCacheable()) { /* Cacheable by default (RFC 9111) */ } if ($status->statusClass() === 4) { /* client error */ } if ($status->category() === 'server_error') { /* 5xx */ } if ($status->phrase() === 'Not Found') { /* Semantic phrases */ } echo StatusCode::NOT_FOUND->toStatusLine(); // 404 Not Found
Content Types
use Philharmony\Http\Enum\ContentType; $contentType = ContentType::JSON; header('Content-Type: ' . $contentType->value); if ($contentType->isTextBased()) { /* Handle text-like responses (JSON, HTML, etc.) */ } if ($contentType->isJson()) { /* Handle json types */ } if ($contentType->isXml()) { /* Handle xml types */ } if ($contentType->isImage()) { /* Handle image types */ } if ($contentType->isAudio()) { /* Handle audio types */ } if ($contentType->isVideo()) { /* Handle video types */ } if ($contentType->isMedia()) { /* Handle audio, video and image types */ } if ($contentType->isFont()) { /* Handle font types */ } if ($contentType->isForm()) { /* Handle for form types */ } if ($contentType->isBinary()) { /* Handle for binary types */ } if ($contentType->isScript()) { /* Handle for script type */ } if ($contentType->isArchive()) { /* Handle for archive type */ } if ($contentType->isCompressible()) { /* Enable gzip/br compression */ } $type = ContentType::fromHeader('application/json; charset=utf-8'); if ($type?->isJson()) { /* Handle JSON */ } $type = ContentType::fromExtension('txt'); header('Content-Type: ' . $type->value); $type = ContentType::fromExtension('.json'); header('Content-Type: ' . $type->value); $type = ContentType::fromFilename('image.png'); header('Content-Type: ' . $type->value); echo ContentType::JSON->baseType(); // 'json' echo ContentType::MP4->category(); // 'video' echo ContentType::JSON->is('application/json'); // true echo ContentType::JSON->is('APPLICATION/JSON'); // true echo ContentType::JSON->matches('application/*'); // true echo ContentType::PNG->matches('image/*'); // true $best = ContentType::negotiate( 'application/json, text/html;q=0.9', [ContentType::JSON, ContentType::HTML, ContentType::XML] );
URI Schemes & Ports
use Philharmony\Http\Enum\Scheme; $scheme = Scheme::HTTPS; echo $scheme->defaultPort(); // 443 if ($scheme->isSecure()) { /* Logic for secure connection (SSL/TLS) */ } if ($scheme->requiresHost()) { /* Logic for requires host */ } if ($scheme->isHttp()) { /* Handle HTTP, HTTPS */ } if ($scheme->isWebSocket()) { /* Handle WS, WSS */ } if ($scheme->isMail()) { /* Handle IMAP, POP, SMTP */ } if ($scheme->isLdap()) { /* Handle LDAP, LDAPS */ }
HTTP Headers
use Philharmony\Http\Enum\HttpHeader; $header = HttpHeader::CONTENT_TYPE; if ($header->isContentHeader()) { /* Handle content headers */ } if ($header->isCacheHeader()) { /* Handle caching logic */ } if ($header->isAuthHeader()) { /* Handle authentication */ } if ($header->isSecurityHeader()) { /* Sensitive headers */ } if ($header->isCors()) { /* CORS headers */ } if ($header->isProxy()) { /* Proxy / forwarded headers */ } if ($header->isConditional()) { /* Conditional requests */ } $header = HttpHeader::fromString('content-type'); echo $header->value; // Content-Type // HttpHeader::X_FORWARDED_FOR $header = HttpHeader::tryFromString('x-forwarded-for');
Authentication Schemes
use Philharmony\Http\Enum\AuthScheme; $scheme = AuthScheme::fromHeader('Bearer token123'); if ($scheme?->isTokenBased()) { /* Handle Bearer or OAuth tokens */ } if ($scheme?->isPasswordBased()) { /* Handle Basic or Digest authentication */ } if ($scheme?->isChallengeBased()) { /* Handle challenge-response auth */ } $scheme = AuthScheme::fromString('basic'); // AuthScheme::BASIC
HTTP Versions
use Philharmony\Http\Enum\HttpVersion; $version = HttpVersion::HTTP_1_1; echo $version->toProtocolString(); // HTTP/1.1 $version = HttpVersion::fromProtocol('HTTP/2'); if ($version === HttpVersion::HTTP_2) { /* HTTP/2 logic */ } $version = HttpVersion::tryFromString('1.1');
Cache-Control Directives
use Philharmony\Http\Enum\CacheDirective; $directive = CacheDirective::MAX_AGE; if ($directive->isExpiration()) { /* max-age, s-maxage */ } if ($directive->isRestriction()) { /* no-cache, no-store */ } if ($directive->isVisibility()) { /* public, private */ } $directive = CacheDirective::fromString('no-cache'); echo $directive->value; // no-cache $directive = CacheDirective::tryFromString('public');
Content Encoding
use Philharmony\Http\Enum\ContentEncoding; $encoding = ContentEncoding::fromString('gzip'); if ($encoding->isCompressed()) { /* Handle compressed response */ } $encoding = ContentEncoding::tryFromString('br');
SameSite Cookie Policy
use Philharmony\Http\Enum\SameSite; $sameSite = SameSite::STRICT; if ($sameSite->isStrict()) { /* Strict cookie policy */ } if ($sameSite->allowsCrossSite()) { /* Allows cross-site cookies */ } $sameSite = SameSite::fromString('lax'); $sameSite = SameSite::tryFromString('none');
โจ Enum Methods
Each enum provides a set of utility methods for semantic checks, parsing, and grouping โ enabling expressive, safe, and framework-agnostic HTTP handling.
๐ท๏ธ HttpMethod
Represents standard HTTP request methods as a backed enum (string).
| Method | Description |
|---|---|
isSafe(): bool |
Returns true for safe methods: GET, HEAD, OPTIONS, TRACE |
isIdempotent(): bool |
Returns true for idempotent methods: GET, HEAD, PUT, DELETE, OPTIONS, TRACE, CONNECT |
isCacheable(): bool |
Returns true for cacheable methods: GET, HEAD |
isReadOnly(): bool |
Returns true for read only methods: GET, HEAD, OPTIONS, TRACE |
isWriteOnly(): bool |
Returns true for write only methods: POST, PUT, PATCH, DELETE, CONNECT |
usuallyHasBody(): bool |
Returns true for methods that typically include a request body: POST, PUT, PATCH |
allowsBody(): bool |
Returns true for write only methods: POST, PUT, PATCH, DELETE |
isValid(string $method): bool |
Checks if the given string is a valid HTTP method (case-sensitive) |
fromString(string $value) |
Creates an instance from a valid method string - used strtoupper for value and from() |
tryFromString(string $value) |
Creates an instance from a valid method string - used strtoupper for value and tryFrom() |
from(string $value) |
Built-in (PHP 8.1+) โ creates an instance from a valid method string |
tryFrom(string $value) |
Built-in (PHP 8.1+) โ returns null if invalid |
Example:
HttpMethod::isValid('POST')โtrueExample:HttpMethod::tryFromString('post')โHttpMethod::POST
๐ข StatusCode
Represents HTTP status codes as a backed enum (int) with semantic grouping and standard reason phrases.
| Method | Description |
|---|---|
isInformational(): bool |
1xx (100โ199) |
isSuccess(): bool |
2xx (200โ299) |
isRedirection(): bool |
3xx (300โ399) |
isClientError(): bool |
4xx (400โ499) |
isServerError(): bool |
5xx (500โ599) |
isError(): bool |
4xx or 5xx โ indicates an error condition |
phrase(): string |
Returns the standard reason phrase (e.g., OK โ "OK", I_M_A_TEAPOT โ "I'm a teapot") |
toStatusLine(): string |
Returns full status line fragment like 404 Not Found |
from(int $code) |
Built-in โ creates from status code |
tryFrom(int $code) |
Built-in โ returns null if invalid |
Static Group Methods (return StatusCode[]):
informational()โ all1xxsuccess()โ all2xxredirection()โ all3xxclientError()โ all4xxserverError()โ all5xxerror()โ all4xxand5xx
Example:
StatusCode::NOT_FOUND->isClientError()โtrue
๐ ContentType
Represents media types as a backed enum (string) with parsing and detection utilities.
| Method | Description |
|---|---|
isTextBased(): bool |
text/*, application/json, application/xml, application/javascript, etc. |
isJson(): bool |
application/json, application/hal+json, application/problem+json, etc. |
isXml(): bool |
application/xml, application/atom+xml, application/rss+xml, application/xhtml+xml, etc. |
isImage(): bool |
image/* |
isAudio(): bool |
audio/* |
isVideo(): bool |
video/* |
isMedia(): bool |
image/*, audio/*, video/* |
isFont(): bool |
font/woff, font/woff2, font/ttf, font/otf |
isForm(): bool |
application/x-www-form-urlencoded, multipart/form-data |
isBinary(): bool |
Includes media, fonts, PDF, ZIP, Protobuf, etc. |
isScript(): bool |
application/javascript |
isArchive(): bool |
application/zip |
isCompressible(): bool |
Returns true for types suitable for compression |
defaultCharset(): ?string |
Returns default charset for text-like types (heuristic) |
baseType(): string |
Returns base subtype (e.g. application/json โ json) |
category(): string |
Returns MIME category (e.g. json, image, video, audio, text) |
is(): bool |
Case-insensitive exact match for MIME type |
matches(): bool |
Pattern match like image/*, application/* |
fromHeader(string $header): ?self |
Parses from Content-Type header (ignores parameters like ; charset=utf-8) |
fromExtension(string $extension): ?self |
Maps file extension (e.g., .json, .png) to content type |
fromFilename(string $filename): ?self |
Maps filename to content type by extension |
negotiate(string $accept, array $available): ?self |
Chooses best type from Accept header (q + specificity) |
from(string $value) |
Built-in โ creates from MIME type |
tryFrom(string $value) |
Built-in โ returns null if invalid |
Static Group Methods (return ContentType[]):
textBased(),json(),xml(),image(),audio(),video(),media(),font(),form(),binary()
Example:
ContentType::fromHeader('application/json; charset=utf-8')โContentType::JSON
๐ Scheme
Represents URI schemes as a backed enum (string) with port mapping.
| Method | Description |
|---|---|
defaultPort(): ?int |
Returns standard port (e.g., HTTP โ 80, HTTPS โ 443, LDAPS โ 636) |
isSecure(): bool |
Returns true for secure protocols: HTTPS, WSS, SFTP, LDAPS, SSH |
requiresHost(): bool |
Returns true for schemes that require a host: HTTP, HTTPS, WS, WSS, FTP, SFTP |
isHttp(): bool |
Returns true for HTTP, HTTPS |
isWebSocket(): bool |
Returns true for WS, WSS |
isMail(): bool |
Returns true for SMTP, IMAP, POP |
isLdap(): bool |
Returns true for LDAP, LDAPS |
fromString(string $scheme) |
Creates enum from scheme string (case-insensitive, trims input) |
tryFromString(string $scheme) |
Safe version returning null if invalid |
๐จ HttpHeader
Represents common HTTP headers as a backed enum (string) with semantic grouping and normalization utilities.
| Method | Description |
|---|---|
isRequestHeader(): bool |
Returns true if header is typically used in HTTP requests |
isResponseHeader(): bool |
Returns true if header is typically used in HTTP responses |
isContentHeader(): bool |
Content-* headers (Content-Type, Content-Length, etc.) |
isCors(): bool |
Access-Control-* headers |
isProxy(): bool |
Proxy headers (X-Forwarded-*, X-Real-IP) |
isCacheHeader(): bool |
Cache-related headers (Cache-Control, ETag, Expires, etc.) |
isAuthHeader(): bool |
Authentication headers (Authorization, WWW-Authenticate, etc.) |
isSecurityHeader(): bool |
Security-sensitive headers (Authorization, Cookie, Set-Cookie) |
isConditional(): bool |
Conditional request headers (If-Match, If-None-Match, etc.) |
isGeneralHeader(): bool |
General headers (Cache-Control, Connection, Date, etc.) |
isRequestOnly(): bool |
Returns true if header is request-only (excludes response/general) |
isResponseOnly(): bool |
Returns true if header is response-only (excludes general) |
isHopByHop(): bool |
Hop-by-hop headers (RFC 7230, includes TE and Trailer) |
fromString(string $header): self |
Creates enum from header name (case-insensitive, trims input) |
tryFromString(string $header): ?self |
Safe version returning null if header is unknown |
from(string $value) |
Built-in โ creates from header string |
tryFrom(string $value) |
Built-in โ returns null if invalid |
Example:
HttpHeader::fromString('content-type')โHttpHeader::CONTENT_TYPEExample:HttpHeader::isRequestOnly()/HttpHeader::isResponseOnly()for request/response-only checks
๐ AuthScheme
Represents HTTP authentication schemes used in the Authorization and WWW-Authenticate headers.
| Method | Description |
|---|---|
isTokenBased(): bool |
Returns true for token-based authentication (Bearer, OAuth) |
isChallengeBased(): bool |
Returns true for challenge-response schemes (Basic, Digest, Negotiate, HOBA, Mutual) |
isPasswordBased(): bool |
Returns true for password-based schemes (Basic, Digest) |
fromHeader(string $header): ?self |
Extracts authentication scheme from Authorization header (case-insensitive) |
fromString(string $scheme) |
Creates enum from scheme name (case-insensitive, trims input) |
tryFromString(string $scheme) |
Same as above but returns null if invalid |
from(string $value) |
Built-in โ creates enum from valid string |
tryFrom(string $value) |
Built-in โ returns null if invalid |
Example:
AuthScheme::fromHeader('Bearer token123')โAuthScheme::BEARERExample:AuthScheme::fromString('basic')โAuthScheme::BASIC
๐ HttpVersion
Represents HTTP protocol versions.
โ
StatusCode Helpers
| Method | Description |
|---|---|
statusClass(): int |
Returns the status code class (1..5) |
category(): string |
Returns semantic category (success, etc.) |
isCacheable(): bool |
Returns true if cacheable by default (RFC 9111) |
| Method | Description |
|---|---|
toProtocolString(): string |
Returns protocol string like HTTP/1.1, HTTP/2 |
fromProtocol(string $protocol) |
Parses version from protocol string (HTTP/1.1, HTTP/2) |
fromString(string $version) |
Creates enum from version string (1.1, 2, 3) |
tryFromString(string $version) |
Safe version returning null if invalid |
from(string $value) |
Built-in โ creates enum from version string |
tryFrom(string $value) |
Built-in โ returns null if invalid |
Example:
HttpVersion::fromProtocol('HTTP/1.1')โHttpVersion::HTTP_1_1
๐๏ธ CacheDirective
Represents Cache-Control directives used to control HTTP caching behavior.
| Method | Description |
|---|---|
isRestriction(): bool |
Returns true for cache restrictions (no-cache, no-store) |
isExpiration(): bool |
Returns true for expiration directives (max-age, s-maxage) |
isVisibility(): bool |
Returns true for cache visibility (public, private) |
fromString(string $directive) |
Creates enum from directive string (case-insensitive) |
tryFromString(string $directive) |
Safe version returning null if directive is unknown |
from(string $value) |
Built-in โ creates enum from valid string |
tryFrom(string $value) |
Built-in โ returns null if invalid |
Example:
CacheDirective::fromString('no-cache')โCacheDirective::NO_CACHE
๐ ContentEncoding
Represents compression algorithms used in Content-Encoding and Accept-Encoding headers.
| Method | Description |
|---|---|
isCompressed(): bool |
Returns true for compression algorithms (all except identity) |
fromString(string $encoding) |
Creates enum from encoding string |
tryFromString(string $encoding) |
Safe version returning null if invalid |
from(string $value) |
Built-in โ creates enum from valid string |
tryFrom(string $value) |
Built-in โ returns null if invalid |
๐ช SameSite
Represents cookie SameSite policies used in Set-Cookie headers to control cross-site request behavior.
| Method | Description |
|---|---|
isStrict(): bool |
Returns true if policy is Strict |
allowsCrossSite(): bool |
Returns true if cookies may be sent with cross-site requests |
fromString(string $value) |
Creates enum from SameSite string |
tryFromString(string $value) |
Safe version returning null if invalid |
from(string $value) |
Built-in โ creates enum from valid string |
tryFrom(string $value) |
Built-in โ returns null if invalid |
๐ RFC Compliance
This library follows behavior defined in several HTTP specifications:
- RFC 9110 โ HTTP Semantics
- RFC 9111 โ HTTP Caching
- RFC 9112 โ HTTP/1.1
- RFC 7231 โ HTTP Methods
- RFC 6265 โ HTTP Cookies (SameSite)
- RFC 6454 โ Web Origin Concept
๐งช Testing
The package is strictly tested with PHPUnit 10 to ensure full compliance with HTTP standards and RFCs.
Run Tests
composer test
Code Coverage
composer test:coverage
๐๏ธ Static Analysis & Code Style
Verified with PHPStan Level 9 to ensure total type safety and prevent runtime errors.
composer phpstan
Check and fix code style (PSR-12):
composer cs-check composer cs-fix
๐ License
This package is open-source and licensed under the MIT License. See the LICENSE file for details.
๐ค Contributing
Contributions, issues, and feature requests are welcome.
If you find a bug or have an idea for improvement, please open an issue or submit a pull request.
โญ Support
If you find this package useful, please consider giving it a star on GitHub. It helps the project grow and reach more developers.