PHPackages                             philharmony/http-message - 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. philharmony/http-message

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

philharmony/http-message
========================

PSR-7 HTTP message implementation with Enum typing for Philharmony

v1.4.0(2mo ago)0176↓90.9%1MITPHPPHP ^8.1CI passing

Since Mar 5Pushed 2mo agoCompare

[ Source](https://github.com/philharmonytech/http-message)[ Packagist](https://packagist.org/packages/philharmony/http-message)[ Docs](https://github.com/philharmonytech/http-message)[ RSS](/packages/philharmony-http-message/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (5)Dependencies (11)Versions (6)Used By (1)

philharmony/http-message
========================

[](#philharmonyhttp-message)

[![Validate](https://github.com/philharmonytech/http-message/actions/workflows/ci.yaml/badge.svg?job=validate)](https://github.com/philharmonytech/http-message/actions/workflows/ci.yaml)[![Analysis](https://github.com/philharmonytech/http-message/actions/workflows/ci.yaml/badge.svg?job=static-analysis)](https://github.com/philharmonytech/http-message/actions/workflows/ci.yaml)[![Test](https://github.com/philharmonytech/http-message/actions/workflows/ci.yaml/badge.svg?job=tests)](https://github.com/philharmonytech/http-message/actions/workflows/ci.yaml)[![codecov](https://camo.githubusercontent.com/1f48136b50151a1d7fb58430ac763cceaae0d296dc21f3434c1e2887dec99f28/68747470733a2f2f636f6465636f762e696f2f6769746875622f7068696c6861726d6f6e79746563682f687474702d6d6573736167652f67726170682f62616467652e7376673f746f6b656e3d4a56474d31525241434b)](https://codecov.io/github/philharmonytech/http-message)[![PHP Version](https://camo.githubusercontent.com/48b43ec8db6cfdd0d482cba4d9f310ad8aacc1dadd96ddda95bf9c2daad8bd52/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e31253230746f253230382e342d3838393242462e737667)](https://www.php.net/supported-versions.php)[![Latest Stable Version](https://camo.githubusercontent.com/4c8d8e40d4d28da0f223290e9506e11fecfcd8dc55733b8b34872699915e4c76/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f7068696c6861726d6f6e79746563682f687474702d6d6573736167653f6c6162656c3d737461626c65)](https://github.com/philharmonytech/http-message/releases)[![Total Downloads](https://camo.githubusercontent.com/621326e1a131d50475dd4fc62591716b63db8ba36a9698dc8cfc6db01328ed34/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7068696c6861726d6f6e792f687474702d6d657373616765)](https://packagist.org/packages/philharmony/http-message)[![License](https://camo.githubusercontent.com/edce5eb84e21c2ffdd60e74b9dd81fbe15fac32c854da8f6b311fc4b91fde728/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7068696c6861726d6f6e792f687474702d6d657373616765)](https://github.com/philharmonytech/http-message/blob/main/LICENSE)

Strict, type-safe **PSR-7 HTTP Message implementation** for modern PHP (8.1+). Designed for maximum security, immutability, and seamless integration with modern PHP 8.1+ ecosystems.

📖 Description
-------------

[](#-description)

`philharmony/http-message` provides a robust, high-performance implementation of the **PSR-7 HTTP Message interfaces**. This package serves as the foundational messaging layer for the Philharmony framework, focusing on:

- **Full PSR-7 Compliance** — Interchangeable with any PSR-compliant library.
- **Strict Typing** — Verified with **PHPStan Level 9** for rock-solid reliability.
- **Security by Design** — Prevents common URI vulnerabilities like path/host ambiguity (RFC 3986).
- **Smart Encoding** — Handles UTF-8 characters and avoids double-encoding of existing percent-encoded sequences.
- **IPv6 &amp; IDN Support** — Fully supports IPv6 hosts and internationalized domain names.
- **Enum Integration** — Works natively with `philharmony/http-enum` for scheme and port logic.
- **Strict Validation** — Prevents invalid hosts and illegal URI characters according to RFC 3986.

✨ Key Features
--------------

[](#-key-features)

- **Full PSR-7 compliance** — Fully compatible with the PHP ecosystem.
- **Strict typing** — Verified with PHPStan Level 9.
- **Immutable design** — Safe for middleware pipelines.
- **IPv6 &amp; IDN support** — Modern host formats supported out of the box.
- **Smart URI encoding** — Prevents double-encoding and handles Unicode safely.
- **Security-focused validation** — Rejects invalid hosts and illegal URI characters.
- **Upload error abstraction** — PHP upload errors wrapped in a type-safe enum.

💡 Why philharmony/http-message?
-------------------------------

[](#-why-philharmonyhttp-message)

While many PSR-7 implementations focus on compatibility, **philharmony/http-message** focuses on:

- **Maximum type safety** through strict typing and PHPStan Level 9 analysis
- **Security-first URI handling** following RFC 3986
- **Modern PHP support** (8.1–8.4)
- **Clean immutable design** optimized for middleware architectures

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

[](#-installation)

Install via Composer:

```
composer require philharmony/http-message
```

⚡ Quick Start
-------------

[](#-quick-start)

A minimal example demonstrating the core PSR-7 objects provided by this package.

```
use Philharmony\Http\Message\Uri;
use Philharmony\Http\Message\Request;
use Philharmony\Http\Message\Response;
use Philharmony\Http\Message\ServerRequest;

// Create a URI
$uri = Uri::create('https://api.example.com/users');

// Create a client request
$request = Request::create('GET', $uri);

// Server-side request (incoming HTTP request)
$serverRequest = ServerRequest::make(
    method: 'POST',
    uri: '/users',
    body: '{"name":"John"}',
    headers: ['Content-Type' => 'application/json']
);

// Access parsed body
$data = $serverRequest->getParsedBody();

// Create a response
$response = Response::create(200)
    ->withHeader('Content-Type', 'application/json');

echo $response->getStatusCode(); // 200
```

🚀 Usage: URI
------------

[](#-usage-uri)

### Creating a URI

[](#creating-a-uri)

```
use Philharmony\Http\Message\Uri;

// From string
$uri = new Uri('https://user:pass@example.com:8080/path?query=1#fragment');

// Using factory method
$uri = Uri::create('https://github.com');

// From parts (parse_url compatible)
$uri = Uri::fromParts([
    'scheme' => 'https',
    'host' => 'api.example.com',
    'path' => '/v1/users'
]);
```

### IPv6 and IDN Hosts

[](#ipv6-and-idn-hosts)

The URI implementation supports modern host formats including IPv6 and internationalized domain names.

```
use Philharmony\Http\Message\Uri;

// IPv6 host
$uri = Uri::create('http://[2001:db8::1]/api');

// IDN host (automatically normalized)
$uri = Uri::create('https://münich.example');
```

### Immutability in Action

[](#immutability-in-action)

As per PSR-7, `Uri` objects are immutable. Every modification returns a new instance. If the new value is identical to the current one, the same instance is returned for performance.

```
$baseUri = Uri::create('http://localhost');

$secureUri = $baseUri
    ->withScheme('https')
    ->withPath('/search')
    ->withQuery('q=php+8');

echo $baseUri; // http://localhost
echo $secureUri; // https://localhost/search?q=php+8
```

### Advanced Encoding

[](#advanced-encoding)

The library automatically handles complex paths and query strings, ensuring they are RFC-compliant.

```
// Handles spaces and special characters
$uri = Uri::create('https://example.com')
    ->withPath('/my documents/notes & tasks');
echo $uri->getPath(); // /my%20documents/notes%20%26%20tasks

// Protects already encoded characters (prevents double % encoding)
$uri = $uri->withQuery('search=php%208');
echo $uri->getQuery(); // search=php%208 (NOT search=php%25208)
```

🚀 Usage: Stream
---------------

[](#-usage-stream)

The `Stream` class provides a type-safe wrapper around PHP resources (`fopen`, `php://memory`, etc.).

### Polymorphic Creation

[](#polymorphic-creation)

The `static create()` method is highly flexible and accepts strings, resources, or existing streams:

```
use Philharmony\Http\Message\Stream;

// Create from string (automatically uses php://memory)
$stream = Stream::create('Body content');

// Create from an existing resource
$resource = fopen('data.txt', 'r+');
$streamFromResource = Stream::create($resource);

// Decorate another PSR-7 Stream
$newStream = Stream::create($streamFromResource);
```

### Direct File Creation

[](#direct-file-creation)

Use `Stream::createFromFile()` to create a stream directly from a file path. This method handles file opening and error management automatically:

```
// Create stream directly from file path
$stream = Stream::createFromFile('document.pdf');

// You can also specify the file mode
$stream = Stream::createFromFile('log.txt', 'a+'); // append mode

// Handle errors gracefully
try {
    $stream = Stream::createFromFile('/path/to/nonexistent.file');
} catch (\RuntimeException $e) {
    echo 'Could not create stream: ' . $e->getMessage();
}
```

**Key benefits:**

- **Simplified creation** — eliminates the need to manually call `fopen()`; the method handles file opening internally.
- **Explicit error handling** — throws `InvalidArgumentException` for empty file names or modes, and `RuntimeException` with detailed error messages if the file cannot be opened (e.g., due to permission issues or non‑existent paths).
- **Consistent interface** — returns a `StreamInterface` instance, maintaining compatibility with other `Stream` creation methods like `create()`.
- **Input validation** — performs basic validation of required parameters (`$fileName` and `$mode` must not be empty) before attempting file operations.

### Safe Operations

[](#safe-operations)

Unlike raw PHP functions, `Stream` ensures that system errors are handled gracefully:

```
$stream = Stream::create('Philharmony');
$stream->write(' Framework');
$stream->rewind();

echo $stream->getContents(); // Philharmony Framework
echo $stream->getSize(); // 21
```

### Predictable Stream Behaviour

[](#predictable-stream-behaviour)

The `Stream` implementation ensures consistent and predictable behavior across different stream types.

- **Automatic rewind for string bodies** — when creating a stream from a non-empty string, the pointer is automatically rewound.
- **Reliable mode detection** — readable and writable capabilities are detected based on the underlying stream mode.
- **Safe string casting** — `__toString()` safely catches all `Throwable` errors as required by PSR-7.
- **Robust size detection** — stream size detection gracefully handles environments where `fstat()` may return unexpected values.

These guarantees make the `Stream` implementation safe to use with memory streams, file streams, and custom PHP resources.

🏗️ Architecture: Base Message
-----------------------------

[](#️-architecture-base-message)

All HTTP entities inherit from the abstract Message class, providing robust header management:

- **Case-insensitive headers** — withHeader('content-type', ...) and getHeader('Content-Type') work seamlessly.
- **Protocol versioning** — Supports HTTP/1.0, 1.1, 2.0.
- **Immutable state** — Every change produces a new instance, preventing side effects in middleware chains.

🚀 Usage: HTTP Messages (Request &amp; Response)
-----------------------------------------------

[](#-usage-http-messages-request--response)

Philharmony provides full implementations of PSR-7 HTTP message types:

- **Request** — client-side HTTP request
- **ServerRequest** — server-side request containing environment data
- **Response** — HTTP response message

All messages extend the base `Message` abstraction and follow a fully immutable design.

### Request (Client Request)

[](#request-client-request)

The `Request` class represents an outgoing HTTP request typically used by HTTP clients.

#### Creating a Request

[](#creating-a-request)

```
use Philharmony\Http\Message\Request;

$request = Request::create(
    'GET',
    'https://api.example.com/users',
    '',
    ['Accept' => 'application/json']
);
```

#### Smart HTTP Method Helpers

[](#smart-http-method-helpers)

Philharmony provides helper methods powered by the `HttpMethod` enum.

```
if ($request->isSafe()) {
    echo "Safe request (GET, HEAD, OPTIONS)";
}

if ($request->isIdempotent()) {
    echo "Request can be safely repeated";
}

if ($request->isHttps()) {
    echo "Secure request";
}
```

### ServerRequest (Server-Side Request)

[](#serverrequest-server-side-request)

`ServerRequest` extends `Request` and represents an incoming HTTP request received by the server.

It provides access to additional environment data such as:

- server parameters (`$_SERVER`)
- cookies (`$_COOKIE`)
- query parameters (`$_GET`)
- uploaded files (`$_FILES`)
- parsed request bodies

#### Creating a ServerRequest

[](#creating-a-serverrequest)

```
use Philharmony\Http\Message\ServerRequest;

$serverRequest = ServerRequest::make(
    method: 'POST',
    uri: '/profile/update',
    serverParams: $_SERVER,
    body: '{"name":"Philharmony"}',
    headers: ['Content-Type' => 'application/json'],
    cookieParams: $_COOKIE
);
```

#### Parsed Body Helpers

[](#parsed-body-helpers)

The request body is automatically parsed depending on the `Content-Type` header.

```
if ($serverRequest->isJson()) {
    $data = $serverRequest->getParsedBody();
}

if ($serverRequest->isForm()) {
    $form = $serverRequest->getParsedBody();
}
```

#### Raw Body &amp; Input Helpers

[](#raw-body--input-helpers)

Convenience helpers allow retrieving input values from query parameters or parsed body data.

Lookup order:

1. Query parameters
2. Parsed request body

```
$raw = $serverRequest->getRawBody();

$userId = $serverRequest->input('user.id', 'guest');

if ($serverRequest->has('token')) {
    // token exists
}
```

### Response

[](#response)

The `Response` class automatically handles **Reason Phrases** using the `Philharmony\Http\Enum\StatusCode`.

```
use Philharmony\Http\Message\Response;

// Automatically sets "201 Created" reason phrase
$response = Response::create(201);
echo $response->getReasonPhrase(); // "Created"

// Fluent interface and smart status checks
$errorResponse = $response
    ->withStatus(403)
    ->withHeader('X-Reason', 'Security');

// Powerful status code helpers powered by Philharmony Enums
if ($response->isInformational()) {
    echo "Status is 1xx";
}

if ($response->isSuccessful()) {
    echo "Status is 2xx (Success!)";
}

if ($response->isRedirection()) {
    echo "Status is 3xx (Redirecting...)";
}

if ($response->isClientError()) {
    echo "Status is 4xx (Bad Request, Unauthorized, etc.)";
}

if ($response->isServerError()) {
    echo "Status is 5xx (Server crashed)";
}

if ($response->isError()) {
    echo "Any error occurred (4xx or 5xx)";
}
```

🚀 Usage: Uploaded Files
-----------------------

[](#-usage-uploaded-files)

Handle file uploads with full PSR-7 compatibility and support for modern PHP features like full\_path (PHP 8.1+).

```
use Philharmony\Http\Message\UploadedFile;

$file = UploadedFile::create(
    fileOrStream: '/tmp/phpYzdqkD',
    size: 1024,
    errorStatus: UPLOAD_ERR_OK,
    clientFilename: 'avatar.png',
    clientMediaType: 'image/png',
    fullPath: 'users/avatars/avatar.png' // PHP 8.1+ support
);

// Integration with ContentType Enum
if ($file->getContentType()?->isImage()) {
    $file->moveTo('/var/www/uploads/profile.png');
}
```

### Upload Error Handling

[](#upload-error-handling)

Upload errors are represented internally by the `UploadError` enum.

```
use Philharmony\Http\Message\Enum\UploadError;

$error = UploadError::from($file->getError());

if ($error->isError()) {
    echo $error->message();
}
```

🔍 Technical Specifications
--------------------------

[](#-technical-specifications)

FeatureImplementation**PHP Version**8.1 / 8.2 / 8.3 / **8.4****PSR Standards****[PSR-7](https://www.php-fig.org/psr/psr-7/)** (HTTP Message Interfaces)**Static Analysis**PHPStan **Level 9** (Max Strictness)**Code Quality**PSR-12, Strict Types, Clean Code**Dependencies**`psr/http-message`, `philharmony/http-enum`🧪 Testing
---------

[](#-testing)

The package is strictly tested with PHPUnit 10 to ensure full compliance with HTTP standards and RFCs.

### Run Tests

[](#run-tests)

```
composer test
```

### Code Coverage

[](#code-coverage)

```
composer test:coverage
```

🏗️ Static Analysis &amp; Code Style
-----------------------------------

[](#️-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
---------

[](#-license)

This package is open-source and licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

🤝 Contributing
--------------

[](#-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
---------

[](#-support)

If you find this package useful, please consider giving it a star on GitHub. It helps the project grow and reach more developers.

###  Health Score

39

—

LowBetter than 85% of packages

Maintenance83

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity47

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

Total

5

Last Release

86d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f4cd2e09bafc7c15e943d0844b81b7cbfe022c3b13a5cfe59b158e01e11a0658?d=identicon)[it-philharmony](/maintainers/it-philharmony)

---

Top Contributors

[![Vyacheslav86RUS](https://avatars.githubusercontent.com/u/51032800?v=4)](https://github.com/Vyacheslav86RUS "Vyacheslav86RUS (91 commits)")

---

Tags

httpresponserequestpsrpsr-7http-messagestreamuri

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/philharmony-http-message/health.svg)

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

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

7.9k1.1B3.7k](/packages/guzzlehttp-psr7)[art4/requests-psr18-adapter

Use WordPress/Requests as a PSR-18 HTTP client

155.7k](/packages/art4-requests-psr18-adapter)

PHPackages © 2026

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