The Request Object
The Rhapsody\Core\Request class provides an object-oriented way to interact with the current HTTP request. It encapsulates all the information about the request, such as GET and POST data, server variables, and uploaded files, making your application more secure and easier to work with.
An instance of the Request object is automatically created and passed as the first argument to every controller method by the router.
Accessing Request Information
Route Pattern Matching
The is() method allows you to check if the request's path matches a given pattern.
This is particularly useful for middleware to conditionally apply logic based on the route.
The method supports a trailing wildcard (*) to match any subpath:
// Check if the current request is for the API
if ($request->is('api/*')) {
// API-specific handling
}
// Check for exact match
if ($request->is('users')) {
// Users page
}
// Check for admin routes
if ($request->is('admin/*')) {
// Admin routes
}
The is() method normalizes both the request path and the pattern by stripping
leading slashes, making it consistent for matching.
Get the Request Path & Method
// In a controller method
public function updateUser(Request $request, string $id): Response
{
// Get the request method (e.g., 'get', 'post')
$method = $request->getMethod(); // "post"
// Get the clean URI path (e.g., '/users/1')
$path = $request->getPath(); // "/users/1"
// ...
}
Retrieving Input (GET, POST, JSON, PUT, etc.)
The getBody() method intelligently handles all input sources:
- If the
Content-Typeisapplication/json, it decodes the JSON payload. - For standard form submissions (
application/x-www-form-urlencoded), it returns$_POST. - For
PUT,PATCH, orDELETErequests with form data, it parsesphp://inputautomatically.
$allInput = $request->getBody();
$email = $allInput['email'] ?? null;
Typed Input Accessors
string(), int(), bool() and array() read a single input value and hand it back as exactly the type you asked for, so you don't need casts or isset() checks. They look in the request body first (form fields or a JSON payload, as described above) and then fall back to the query string.
$name = $request->string('name'); // '' when missing
$page = $request->int('page', 1); // 1 when missing or not an integer
$active = $request->bool('active'); // false when missing
$tags = $request->array('tags'); // [] when missing or not an array
// ?tags[]=php&tags[]=twig gives ['php', 'twig']
| Method | Accepts | Gives the default when |
|---|---|---|
string($key, $default = '') | Strings, ints, floats and bools (converted to a string) | The value is missing, null, or an array |
int($key, $default = 0) | Ints and integer-like strings such as '42' or '-7' | The value is anything else, including '1.5', '12abc', an empty string, or a decimal number |
bool($key, $default = false) | true/false, 1/0, and the strings true, false, on, off, yes, no (case-insensitive) | The value is anything else. An empty string is read as false, not as the default |
array($key) | Arrays, such as tags[]=a&tags[]=b or a JSON array | The value is missing or not an array (it always returns []; there is no default argument) |
A typical controller reads like this:
public function showUsers(Request $request): Response
{
$page = $request->int('page', 1);
$sort = $request->string('sort', 'name');
$subscribed = $request->bool('subscribed'); // an unchecked checkbox is never submitted, so this is false
$roles = $request->array('roles');
// ...
}
What the Accessors Do Not Do
- They never throw. A bad or missing value quietly becomes the default. If a value is required, check it with the Validator and reject the request. (This is the opposite of the
Configreader, which throws on a missing or wrongly-typed key. See Support Helpers.) - They don't validate or sanitize.
int()guarantees you receive an integer, not a sensible one, so clamp or range-check values like page numbers and limits yourself.string()returns the text exactly as it was sent, without the HTML-encoding thatgetQueryParam()applies, so escape it on output (Twig does this automatically) and never build SQL from it. - They work on the Request's own data. Unlike
getQueryParam(), which reads PHP's$_GETdirectly, these methods use the data theRequestwas built with. That makes them work with requests created byRequest::create()in your tests (see Unit Testing).
input() and all()
The accessors above are built on input(), which returns a single raw value (body first, then the query string) or a default of your choosing. all() returns every input value at once: the query string and the request body merged, with body values winning when a key appears in both.
$value = $request->input('q', 'none'); // raw value, any type
$data = $request->all(); // query string + body
Retrieving Individual Query Parameters
To get a value from the URL's query string (e.g., /users?page=2), use the getQueryParam() method. It includes a second argument to specify a default value if the parameter is not present.
public function showUsers(Request $request): Response
{
$currentPage = (int) $request->getQueryParam('page', 1);
// ...
}
All Query Parameters
Use allQueryParams() to retrieve an associative array of all GET parameters from the current request. This is useful when you need to inspect or forward the entire query string.
$params = $request->allQueryParams();
// e.g., ['page' => 2, 'sort' => 'asc', 'filter' => 'active']
Canonical URL
The getCanonicalUrl() method builds a clean, SEO‑friendly canonical URL for the current request. It automatically:
- Detects the correct protocol (
http://orhttps://). - Uses the host from
$_SERVER['HTTP_HOST']. - Strips the path to its bare structure (no extra text).
- Retains only allowed query parameters (by default, only
pageis kept).
This method is used internally by the main layout to generate the <link rel="canonical"> tag, but you can also call it manually if you need the value elsewhere.
// Keep only 'page' and 'category' in the canonical URL
$canonical = $request->getCanonicalUrl(['page', 'category']);
Retrieving Uploaded Files
You can access information about uploaded files using the getFiles() method, which returns the contents of the $_FILES superglobal.
public function handleUpload(Request $request): Response
{
$files = $request->getFiles();
$avatar = $files['avatar'] ?? null;
if ($avatar && $avatar['error'] === UPLOAD_ERR_OK) {
// Process the uploaded file
}
// ...
}
Direct Access to Raw Data
If you need to access raw GET or POST values directly, you can use the get() and post() methods:
$userId = $request->get('user_id'); // from $_GET
$email = $request->post('email'); // from $_POST