Skip to content

Repository files navigation

AlfaCode HTTP

CILicense: MITPHP ^8.4

The HTTP layer of the PhpServicePlatform kernel: a small, immutable Request/Response surface with a PSR-7 Uri, content negotiation, absolute-URL generation, and FPM- and OpenSwoole-safe file uploads. Built on Symfony HttpFoundation for a battle-tested parser/emitter, but exposed through its own API so callers never depend on Symfony types directly.

Package: alfacode-team/http · Namespace: AlfacodeTeam\PhpServicePlatform\Kernel\Http\

Why

  • Immutable Request. Every mutator (withHeader, withAttribute, merge, …) returns a new instance; __clone() deep-clones parameter bags so clones are fully isolated — required for OpenSwoole/coroutine safety.
  • One Response type. Named constructors (json, html, redirect, stream, download, …) instead of a zoo of response classes.
  • No hidden globals. Nothing in this layer reaches for a container or config singleton; dependencies are passed in.
  • Engine-agnostic API. Consumers use $request->input() / Response::json(), never Symfony\...\Request — so the underlying engine can change without breaking you.

Install

composer require alfacode-team/http

Requires PHP 8.4+ and the symfony/http-foundation + symfony/mime runtime deps (installed automatically).

Usage

Reading the request (immutable)

useAlfacodeTeam\PhpServicePlatform\Kernel\Http\Request;
$request = Request::capture();
$request->method(); // 'POST' (always upper-case)$request->path(); // '/api/invoices'$request->isMethod('post'); // true$request->isSecure(); // honours X-Forwarded-Proto// Input — body + query merged; JSON bodies decoded automatically$request->input('title', 'Untitled');
$request->all();
$request->only(['title', 'amount']);
$request->boolean('active'); // "1"/"true"/"on"/"yes" → true$request->integer('page');
$request->query('page');
$request->header('Accept'); // case-insensitive$request->bearerToken(); // from Authorization: Bearer …$file = $request->file('avatar'); // ?UploadedFile// Routing / negotiation helpers$request->segments(); // ['api', 'invoices']$request->is('api/*'); // wildcard path match$request->expectsJson();

Immutable mutators return a new request, leaving the original untouched:

$request = $request->withAttribute('locale', 'fr')
->withHeader('X-Trace', $id)
->merge(['source' => 'import']);

Building a response (one type, immutable)

useAlfacodeTeam\PhpServicePlatform\Kernel\Http\Response;
return Response::json($data, 201);
return Response::created($data, location: "/api/invoices/{$id}");
return Response::noContent(); // 204return Response::redirect('/login');
// Error envelopes: { "error": { "code", "message"[, "fields"] } }return Response::notFound();
return Response::unprocessable(['email' => 'Required.']); // 422return Response::tooManyRequests(retryAfter: 30);
// Streaming / files — work on BOTH PHP-FPM and OpenSwoolereturn Response::stream(fn () => print(generateCsv()));
return Response::download($path, 'report.pdf');
// Immutable chainingreturn Response::json($data)
->withHeader('Cache-Control', 'no-store')
->withCookie('sid', $token, maxAge: 3600);

URLs & negotiation

// PSR-7 Uri from the current request$login = (string) $request->uri()->withPath('/login')->withQuery('');
// Host-aware absolute URLs (OAuth callbacks, email links, sitemaps)$callback = $request->site()->to('auth/callback');
// Content negotiation from Accept-* headers$locale = $request->negotiate()->language(['en', 'fr', 'ar']);
$type = $request->negotiate()->media(['application/json', 'text/csv']);

Typed HTTP methods

useAlfacodeTeam\PhpServicePlatform\Kernel\Http\Method;
$m = Method::from($request->method());
$m->isSafe(); // GET/HEAD/OPTIONS/TRACE$m->isIdempotent(); // + PUT/DELETE

Uploads — FPM-safe and Swoole-safe

$file = $request->file('avatar');
if ($file !== null && $file->isValid()) {
$file->move($dir, $generatedName); // move_uploaded_file on FPM; rename on Swoole
}

What's inside

ClassRole
RequestFinal, immutable request; extends Symfony's Request behind the kernel API
ResponseSingle response type — json/html/text/stream/download/redirect/…
UploadedFileFPM-safe (is_uploaded_file check) and Swoole-safe (fromSwoole)
UriImmutable PSR-7 UriInterfaceRequest::uri()
SiteUriAbsolute-URL generator (host-aware) → Request::site()
NegotiateAccept-* content negotiation → Request::negotiate()
MethodHTTP method enum with isSafe() / isIdempotent() semantics
UserAgentParsed user-agent value object
Concerns\ManagesResponseShared immutable response accessors/mutators
Contracts\RequestAwaresetRequest(Request): static — the only kernel↔controller seam

Notes for standalone use

This package is extracted from the PhpServicePlatform kernel. A couple of methods — Request::withIdentity()/identity() and Request::withContainer()/container() — type-hint the kernel's Identity and ModuleContainer. Those are optional: they are only resolved when a host framework calls them, so the request/response/URI/upload surface is fully usable on its own.

Testing

composer install
composer test# phpunit
composer analyse # phpstan
composer check # both

Contributing

Contributions are welcome — see CONTRIBUTING.md. Please run composer check before opening a pull request. This project follows a Code of Conduct; by participating you agree to uphold it.

Security

Found a vulnerability? Please follow the Security Policy and report it privately — never in a public issue.

License

MIT © AlfaCode Team — see LICENSE.

About

Immutable HTTP request/response value objects, PSR-7 URI, content negotiation and Swoole-safe uploads for the PhpServicePlatform kernel.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages