Skip to content

Repository files navigation

Effectra HTTP Message

A PSR-7 HTTP message library for PHP 8.1+.

Installation

composer require effectra/http-message

Requirements

  • PHP ^8.1
  • psr/http-message ^1.1 || ^2.0

Package Features

  • PSR-7 compliantRequest, Response, ServerRequest, Uri, Stream, UploadedFile, Message
  • Case-insensitive headershasHeader(), getHeader(), withHeader(), etc. all normalize to lowercase
  • Immutable with* methods — all PSR-7 with* methods return new instances; mutable set* methods are also available
  • Response factorieswithJson(), static json(), static html(), static emptyResponse()
  • ServerRequest utilitiesfromGlobals() factory, replaceHeader() helper
  • Stream from file path — constructor accepts a file path string and opens it as a resource
  • UploadedFilegetStream() reads from the actual uploaded file
  • PHP 8 featuresfinal classes, readonly properties, #[Immutable] attribute
  • Comprehensive test suite — 196+ tests, PHPStan level 6 clean

Usage

Creating a Request

useEffectra\Http\Message\Request;
useEffectra\Http\Message\Uri;
$uri = newUri('https://api.example.com/users');
$request = newRequest('POST', $uri, ['Content-Type' => 'application/json'], '{"name":"John"}');
echo$request->getMethod(); // POSTecho$request->getHeaderLine('Content-Type'); // application/json

Immutable with* methods:

$new = $request->withMethod('PUT')->withUri(newUri('https://other.com'));
// $request is unchanged

Mutable set* methods:

$request->setMethod('PATCH')->setUri(newUri('/local'));
// $request is modified in place

Creating a Response

useEffectra\Http\Message\Response;
$response = newResponse(200, ['X-Custom' => 'value'], 'OK');
echo$response->getStatusCode(); // 200echo$response->getReasonPhrase(); // OK

Response Factories

// JSON response$res = Response::json(['status' => 'ok']);
$res = (newResponse())->withJson(['error' => 'bad'], 400);
// HTML response$res = Response::html('<h1>Hello</h1>', 200);
// Empty response (e.g. 204 No Content)$res = Response::emptyResponse(204);

All standard HTTP status codes (100–511) are available as class constants:

Response::HTTP_OK; // 200
Response::HTTP_NOT_FOUND; // 404
Response::HTTP_I_AM_A_TEAPOT; // 418

ServerRequest (from globals)

useEffectra\Http\Message\ServerRequest;
$request = ServerRequest::fromGlobals();
echo$request->getMethod(); // GET, POST, etc.echo$request->getServerParams()['REMOTE_ADDR'];
$input = $request->getParsedBody(); // POST / JSON body

Working with URIs

useEffectra\Http\Message\Uri;
$uri = newUri('https://example.com/path?q=hello#section');
echo$uri->getScheme(); // httpsecho$uri->getHost(); // example.comecho$uri->getPath(); // /pathecho$uri->getQuery(); // q=hello$new = $uri->withScheme('http')->withHost('other.org');

Stream

useEffectra\Http\Message\Stream;
// From a string$stream = newStream('content');
echo$stream->getContents(); // content// From a file path (opens automatically)$stream = newStream('/path/to/file.txt');
// From a resource$stream = newStream(fopen('php://memory', 'r+'));
$stream->write('data');

Uploaded Files

useEffectra\Http\Message\UploadedFile;
$file = newUploadedFile(
$_FILES['avatar']['tmp_name'],
$_FILES['avatar']['size'],
$_FILES['avatar']['error'],
$_FILES['avatar']['name'],
$_FILES['avatar']['type']
);
$stream = $file->getStream(); // read file contentsecho$file->getClientFilename(); // original name$file->moveTo('/storage/avatars/1.jpg');

Case-Insensitive Headers

All header operations are case-insensitive:

$request = newRequest('GET', '/', ['Content-Type' => 'text/html']);
$request->hasHeader('content-type'); // true$request->hasHeader('CONTENT-TYPE'); // true$request->hasHeader('Content-Type'); // true$request->getHeader('CONTENT-TYPE'); // ['text/html']$cloned = $request->withoutHeader('content-type');
$cloned = $request->withAddedHeader('X-Custom', 'val');

Attributes (PHP 8)

useEffectra\Http\Message\Attribute\Immutable;
#[Immutable('This class follows the PSR-7 immutable pattern')]
class MyMessage
{
// ...
}

#[Immutable] and #[Deprecated] attributes are available for documentation and static analysis.

PHPStan

composer run phpstan

Level 6 with baseline. The _ide_helper.php file provides additional type information for better IDE support.

Testing

composer test

Contributing

Contributions are welcome. Please open an issue or submit a pull request.

License

MIT

About

Effectra/Http-Message: A PHP library implementing PSR-7 for standardized handling of HTTP requests and responses.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages