httpsoft/http-server-request
PSR-7/PSR-17 friendly ServerRequest implementation and helpers for building HTTP server requests in PHP. Lightweight, standards-based request object with convenient access to headers, cookies, query params, body, uploaded files, and server params.
Install via Composer
composer require httpsoft/http-server-request
Create a ServerRequest from superglobals (most common use case)
use HttpSoft\ServerRequest\ServerRequestFactory;
$request = (new ServerRequestFactory())->createServerRequestFromGlobals();
Use it in middleware
Since itβs PSR-7 compliant, plug it directly into any PSR-15/PSR-15-compatible middleware stack (e.g., with Nyholm/psr7, Relay, or custom dispatcher):
$request = (new ServerRequestFactory())->createServerRequestFromGlobals();
$response = $middleware($request, $response);
π‘ First-tip: Start with
ServerRequestFactory::createServerRequestFromGlobals()β it handles all the superglobal parsing (including$_COOKIE,$_FILES,$_SERVER) with PSR-7 normalization.
Use the request as the standard interface for handling requests in middleware:
$app = function ($request) {
$method = $request->getMethod();
$path = $request->getUri()->getPath();
return new JsonResponse(['path' => $path, 'method' => $method]);
};
Build requests programmatically (e.g., for testing or CLI-initiated HTTP flows):
$request = (new ServerRequestFactory())->createServerRequest(
'POST',
'/api/upload',
[
'Content-Type' => 'multipart/form-data; boundary=----WebKit',
'Authorization' => 'Bearer xyz'
],
$_COOKIE,
$_GET,
$_POST,
$_FILES
);
Access uploaded files with normalized PSR-7 structures:
$uploadedFiles = $request->getUploadedFiles();
$file = $uploadedFiles['avatar'] ?? null;
if ($file instanceof UploadedFileInterface && $file->getError() === UPLOAD_ERR_OK) {
$file->moveTo('/var/www/uploads/' . $file->getClientFilename());
}
Since the package supports body parsing:
if ($request->hasHeader('Content-Type') && strpos($request->getHeaderLine('Content-Type'), 'application/json') !== false) {
$parsedBody = $request->getParsedBody(); // e.g., ['name' => 'Jane', 'age' => 30]
}
π‘ Pattern tip: Combine with
httpsoft/psr7for full PSR-7/18 compatibility in non-framework apps.
$_COOKIE is parsed only if setCookieParse() isnβt overridden β default behavior follows PHPβs mb_parse_str()-style rules, but httpsoft/http-server-request parses cookies more robustly (e.g., handles nested arrays). Double-check complex cookie structures.$_FILES structure must match PHPβs array format β if mocking in tests, use this format:
$_FILES = [
'avatar' => [
'name' => 'me.jpg',
'type' => 'image/jpeg',
'tmp_file' => '/tmp/php123',
'error' => 0,
'size' => 12345,
]
];
__toString() on requests to debug headers/body (debug-only β not for prod):
error_log((string) $request);
createServerRequestFromGlobals() to avoid side effects.ServerRequestFactory to override parsing behavior (e.g., custom body parsers or header normalization).withParsedBody() returns a new instance β always reassign:
// β Wrong: ignored
$request->withParsedBody(['foo' => 'bar']);
// β
Correct
$request = $request->withParsedBody(['foo' => 'bar']);
π‘ Pro tip: For apps not using a framework, combine this with
httpsoft/psr17-factoryto satisfy full PSR-17/18 expectations across the stack.
How can I help you explore Laravel packages today?