Server request
The request object based on PSR-7: Server Request.
A request built from what PHP hands the process — $_SERVER, $_GET, $_COOKIE, $_FILES and the body — and answered for the way PSR-7 says it should be. Every part of it is a parameter bag, so reading something which was not sent is an answer rather than a notice.
Requirements
- PHP 8.1 or newer
Installation
composer require quillstack/server-requestUsage
Building one from what arrived
$request = $factory->createServerRequest();
$request->getMethod(); // 'GET'
$request->getUri()->getPath(); // '/users/42'
$request->getHeaderLine('accept'); // 'application/json'
$request->getRequestTarget(); // '/users/42?page=2'
$request->getQueryParams(); // ['page' => '2']
$request->getCookieParams();
$request->getParsedBody();The query parameters come from $_GET rather than from the URI, which is what PSR-7 allows and what everything else in PHP does — so a rewritten URL and the parameters PHP parsed cannot disagree.
Attributes
What the router matched arrives here, and anything else a middleware wants to hand along:
$request = $request->withAttribute('id', '42');
$request->getAttribute('id'); // '42'
$request->getAttribute('page', '1'); // '1' — nothing under that nameEvery change hands back a copy, so a middleware adding one does not change the request anybody else is holding.
A request class of your own
A controller can be handed a request of its own type, so what an endpoint expects is a class rather than a convention:
$factory->setRequestClass(UserRequest::class);The class has to exist; UnknownServerRequestClassException says so when it does not.
Uploaded files
foreach ($request->getUploadedFiles() as $name => $file) {
$file->getClientFilename(); // 'photo.jpg'
$file->getClientMediaType(); // 'image/jpeg'
$file->getSize(); // 20481
$file->getError(); // UPLOAD_ERR_OK
$file->moveTo('/var/www/uploads/photo.jpg');
}A file can only be moved once — moving it again throws UploadedFileAlreadyMovedException, because the second call would otherwise fail in a way nobody expects. getStream() after a move throws for the same reason.
Technical documentation
| Class | What it is |
|---|---|
ServerRequest | the request, implementing Psr\Http\Message\ServerRequestInterface |
Factory\ServerRequest\ServerRequestFactory | builds one from given parameters |
Factory\ServerRequest\ServerRequestFromGlobalsFactory | builds one from what PHP was given |
Factory\ServerRequest\GivenServerRequestFromGlobalsFactory | the same, as a named class |
UploadedFiles\UploadedFile | one uploaded file, implementing UploadedFileInterface |
UploadedFiles\UploadedFileFactory | turns $_FILES into those |
| Exception | Thrown when |
|---|---|
RequiredParamFromGlobalsNotFoundException | $_SERVER is missing something a request needs |
ServerRequestMethodNotKnownException | the method is not one HTTP has |
UnknownServerRequestClassException | the request class named does not exist |
ServerParamNotSetException | a parameter the factory was told to use is not there |
UploadedFileNotUploadedException | the file did not arrive as an upload |
UploadedFileAlreadyMovedException | it has been moved once already |
UploadedFileNotMovedException | moving it failed |
getRequestTarget() is the path and the query string, taken from the URI — the path is already an absolute one, so nothing is added to the front of it.
Unit tests
composer test
composer test:coverage
composer stanDocker
docker-compose up -d
docker exec -w /var/www/html -it quillstack_server-request shLicense
MIT. See LICENSE.