Requests and Responses
Derafu\Http\Request and Derafu\Http\Response wrap PSR-7 messages and add shortcuts for the things an application does all the time: reading input, negotiating the format and building common responses.
Request
Request implements PSR-7’s ServerRequestInterface, so everything from PSR-7 is available. It is created by RequestFactoryMiddleware, which means a handler or any middleware after it receives a Derafu\Http\Request.
Reading input
$id = $request->query('id', 0); // From the query string.
$name = $request->post('name'); // From the parsed body (form).
$token = $request->header('X-Token', ''); // First value of a header.
if ($request->isJson()) {
$data = $request->json(); // Decoded array, or null.
}
$all = $request->all();
$email = $request->input('email', '');
$some = $request->only(['name', 'email']);
| Method | Returns |
|---|---|
query($key, $default) |
A value from the query string |
post($key, $default) |
A value from the parsed body, or the default when the body is not an array |
header($name, $default) |
The first value of a header, or the default |
isJson() |
Whether Content-Type contains application/json |
json() |
The decoded JSON body as an array, or null when the request is not JSON, the body is invalid, or it does not decode to an array |
all() |
Query, parsed body and JSON body merged, in that order: a later source wins on the same key |
input($key, $default) |
A value from all() |
only($keys) |
The given keys from all() |
Files
if ($request->hasFile('document')) {
$file = $request->file('document'); // PSR-7 UploadedFileInterface.
}
$files = $request->files();
hasFile() is true only when the file was uploaded without error. file() returns null when there is no such file.
Application context
| Method | Returns |
|---|---|
route() |
The RouteMatchInterface stored by RouterMiddleware |
session() |
The session, stored by the session middleware |
flash() |
The flash messages, stored by the flash middleware |
user() |
The authenticated user, or null |
route(), session() and flash() throw a LogicException when the middleware that provides them did not run before. user() never throws.
Content negotiation
The request decides which format the client wants, and the response, errors included, follow it. getPreferredContentType() checks, in this order:
- The extension in the URL:
/report.jsonmeans JSON,/page.htmlmeans HTML. - Whether it is an API request, that is the path is
/apior starts with/api/: JSON. - Whether it is an XHR request (
X-Requested-With: XMLHttpRequest): JSON. - The
Acceptheader, ordered by itsqvalues. The first ofapplication/json,text/htmlortext/plainthat appears wins. - HTML, when there is no
Acceptheader or none of those is in it.
getPreferredFormat() returns the same as a subtype string (json, html, …). isApiRequest() and isXmlHttpRequest() expose the individual checks.
Response
use Derafu\Http\Enum\HttpStatus;
use Derafu\Http\Response;
return (new Response())
->asJson(['id' => 42])
->withHttpStatus(HttpStatus::CREATED);
| Method | What it does |
|---|---|
asJson($data, $flags) |
JSON body with Content-Type: application/json. Throws a JsonException if the data can not be encoded. The default flags do not escape slashes or unicode |
asText($data, $type) |
Text body; $type is a ContentType, ContentType::PLAIN by default |
asHtml($html) |
HTML body |
redirect($url, $status) |
Location header and empty body. HttpStatus::FOUND (302) by default |
withHttpStatus($status) |
Sets the status code and reason phrase from an HttpStatus |
withContentType($type) |
Sets Content-Type, adding charset=UTF-8 to text types |
Returning data instead of a response
A handler does not have to build a Response. If it returns an array, a string or an object, ResponseNormalizerMiddleware turns it into one using the preferred content type of the request. See Middleware.
public function show(string $id): array
{
// Sent as JSON to an API client.
return ['id' => $id];
}
Build the Response yourself when you need control over the status or the headers.
Enums
ContentType
Derafu\Http\Enum\ContentType lists the media types the library knows. Besides its value (the media type string) it provides:
| Method | Purpose |
|---|---|
fromFilename($name), fromExtension($ext) |
Find the type from a file name or extension; OCTET_STREAM when unknown |
withCharset($charset) |
The media type with ; charset=... appended |
getMainType(), getSubType() |
application and json for application/json |
isText(), isImage(), isAudio(), isVideo(), isFont() |
Group checks |
isStatic() |
Whether it is a known file type: everything except OCTET_STREAM. It is what StaticFilesMiddleware uses |
HttpStatus
Derafu\Http\Enum\HttpStatus has a case for each status code, for example HttpStatus::NOT_FOUND. It provides getReasonPhrase() and the checks isInformational(), isSuccessful(), isRedirection(), isClientError(), isServerError() and isError().