HTTP Requests
Introductionβ
An HTTP request is the message that the user sends to the Bow application through their browser or other tools such as curl, httpie, etc.
This message is handled by Bow via the Bow\Http\Request class. This class provides access to the request information: IP address, HTTP method, form data, uploaded files, etc.
Accessing the requestβ
Via the helperβ
$request = request();
$name = $request->get('name');
Via dependency injectionβ
use Bow\Http\Request;
$app->get('/', function (Request $request) {
return $request->get('name');
});
Via a controllerβ
namespace App\Controllers;
use App\Models\User;
use Bow\Http\Request;
class UserController
{
public function show(Request $request, int $id)
{
$user = User::retrieve($id);
$user->name = $request->get('name');
$user->persist();
return view('user/profile', ['user' => $user]);
}
}
Retrieving dataβ
Retrieving a valueβ
// Via the get() method
$name = $request->get('name');
// Via the magic property
$name = $request->name;
// With a default value
$name = $request->get('name', 'InvitΓ©');
// With a default callback
$name = $request->get('name', fn() => User::first()->name);
// input() is an alias of get()
$name = $request->input('name', 'InvitΓ©');
Retrieving a booleanβ
boolean() casts an input to a real bool. The values 1, "1", true,
"true", "on" and "yes" are considered true; everything else is false.
Handy for checkboxes and feature toggles:
// ?subscribe=on -> true
if ($request->boolean('subscribe')) {
// The box is checked
}
// Absent key returns the default (false by default)
$remember = $request->boolean('remember', true);
Retrieving all the dataβ
$data = $request->all();
Data by source: query string vs POSTβ
When you want to explicitly read $_GET or $_POST (instead of the
merged array returned by all()), use query() and post():
// Full $_GET array
$queryParams = $request->query();
// A specific $_GET key (returns null if absent)
$page = $request->query('page');
// With a default value when the key is absent
$page = $request->query('page', 1);
// Full $_POST array
$body = $request->post();
// A specific $_POST key (with an optional default)
$name = $request->post('name', 'Anonymous');
get()?get($key) first looks in the merged routes/query/body and offers a
default fallback (get('name', 'InvitΓ©')). Reserve query() / post()
for cases where the origin of the data matters (e.g. never reading
?admin=1 from the URL).
JSON and PUT bodiesβ
Bow automatically decodes the request body: if the Content-Type
header is application/json, the JSON is decoded and merged into the
data accessible via get(), all() and post(). No manual step
is required to consume a JSON API:
// POST request with Content-Type: application/json and body {"name": "Franck"}
$name = $request->get('name'); // "Franck"
$body = $request->post(); // ['name' => 'Franck']
PUT request bodies (form-urlencoded) are also parsed
automatically and available through the same methods.
If the Content-Type is application/json but the body is not valid
JSON, Bow throws a Bow\Http\Exception\BadRequestException.
Filtering dataβ
// Retrieve only certain fields
$data = $request->only(['name', 'email']);
// Exclude certain fields
$data = $request->ignore(['password', 'password_confirmation']);
// Both also accept a list of arguments
$data = $request->only('name', 'email');
$data = $request->ignore('password', 'password_confirmation');
Checking existenceβ
if ($request->has('name')) {
// The field exists
}
Retrieving old valuesβ
After a redirect with validation errors:
$oldName = $request->old('name', 'Valeur par dΓ©faut');
Uploaded filesβ
Retrieving a fileβ
$file = $request->file('avatar');
if ($file) {
$file->moveTo('/uploads/avatars');
}
Multiple filesβ
$files = $request->file('documents');
foreach ($files as $file) {
$file->moveTo('/uploads/documents/' . $file->getClientFilename());
}
Checking existenceβ
if (Request::hasFile('avatar')) {
// A file has been uploaded
}
Request informationβ
URL and pathβ
// Request path (e.g. /users/1)
$path = $request->path();
// Full URL (e.g. https://example.com/users/1)
$url = $request->url();
// Origin (e.g. https://example.com)
$origin = $request->origin();
// Hostname (e.g. example.com)
$host = $request->hostname();
// Domain without port (e.g. example.com)
$domain = $request->domain();
Checking the pathβ
if ($request->is('users/*')) {
// The request starts with /users/
}
HTTP methodβ
$method = $request->method(); // GET, POST, PUT, DELETE, etc.
// Quick checks
if ($request->isGet()) { }
if ($request->isPost()) { }
if ($request->isPut()) { }
if ($request->isDelete()) { }
// Match an arbitrary method (case-insensitive)
if ($request->isMethod('patch')) { }
Request typeβ
// AJAX request
if ($request->isAjax()) {
// AJAX handling
}
// Request expecting JSON
if ($request->wantsJson()) {
return response()->json($data);
}
Client informationβ
IP address and portβ
$ip = $request->ip();
$port = $request->port();
User Agentβ
$userAgent = $request->userAgent();
Language and localeβ
$lang = $request->lang(); // e.g. "fr"
$locale = $request->locale(); // e.g. "fr_FR"
Refererβ
$referer = $request->referer();
if ($request->isReferer('https://google.com/*')) {
// The user comes from Google
}
Protocol and securityβ
$protocol = $request->protocol(); // http or https
if ($request->isSecure()) {
// HTTPS connection
}
if ($request->isProtocol('https')) {
// Same thing
}
HTTP headersβ
Retrieving a headerβ
$contentType = $request->getHeader('content-type');
$authorization = $request->getHeader('authorization');
Bearer tokenβ
bearerToken() extracts the token from an Authorization: Bearer <token>
header and returns null when it is missing or malformed:
// Authorization: Bearer eyJhbGci...
$token = $request->bearerToken(); // "eyJhbGci..."
Retrieving all headersβ
$headers = $request->getHeaders();
Checking existenceβ
if ($request->hasHeader('x-api-key')) {
$apiKey = $request->getHeader('x-api-key');
}
Request identifierβ
Each request has a unique identifier:
$requestId = $request->id();
// or
$requestId = $request->getId();
// Set a custom ID
$request->setId('custom-request-id');
Session and authenticationβ
Accessing the sessionβ
$session = $request->session();
$session->put('key', 'value');
Authenticated userβ
$user = $request->user();
// With a specific guard
$user = $request->user('api');
Cookiesβ
// Retrieve all cookies
$cookies = $request->cookie();
// Retrieve a specific cookie
$token = $request->cookie('remember_token');
Validationβ
Validate data directly from the request:
$validation = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email',
'password' => 'required|min:8'
]);
if ($validation->fails()) {
return back()->withErrors($validation->getMessages());
}
Bags (shared data)β
Bags allow you to store values within a single request (for example permissions resolved by a middleware, which a controller will then read) without polluting the inputs.
// Set / read a value
$request->setBag('user_permissions', ['read', 'write']);
$permissions = $request->getBag('user_permissions');
// Read / replace the entire bags array
$all = $request->getBags();
$request->setBags(['user_permissions' => ['read'], 'feature_flags' => ['v2']]);
Request timeβ
$timestamp = $request->time();
Summary tableβ
| Method | Description |
|---|---|
get($key, $default) | Retrieves a value (all sources merged) |
input($key, $default) | Alias of get() |
boolean($key, $default) | Retrieves a value cast to bool |
query($key = null, $default = null) | Query string parameters ($_GET) |
post($key = null, $default = null) | POST body data ($_POST) |
all() | All the data |
only($keys) | Filter by keys |
ignore($keys) | Exclude keys |
has($key) | Checks existence |
file($key) | Retrieves a file |
path() | Request path |
url() | Full URL |
method() | HTTP method |
isMethod($method) | Check the HTTP method |
ip() | Client IP address |
getHeader($key) | HTTP header |
bearerToken() | Authorization: Bearer token |
session() | Session instance |
user($guard) | Authenticated user |
validate($rules) | Validates the data |
setBag($name, $value) / getBag($name) | Data shared within the request |
Is something missing?
If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.