The Request object carries considerably more than just form input — headers, raw JSON payloads, the client's IP address, and details about the current domain are all available through the same object already type-hinted into most controller methods.
Getting a specific header
public function store(Request $request)
{
$apiKey = $request->header('X-Api-Key');
$userAgent = $request->header('User-Agent');
}
Getting all headers
$headers = $request->headers->all(); // an array of all incoming headers
Getting JSON POST data from the request body
// for a request sent with Content-Type: application/json
$name = $request->input('name'); // works for both JSON and form-encoded bodies
$data = $request->json()->all(); // explicitly reads from the JSON payload
$raw = $request->getContent(); // the raw, unparsed request body as a string
$request->input() is usually all you need — Laravel automatically detects a JSON content type and merges the decoded payload into the same input bag form data would populate, which is why the same method works for both.
Getting the client's IP address
$ip = $request->ip();
Behind a load balancer or reverse proxy, $request->ip() can return the proxy's own IP rather than the actual client's, unless Laravel's trusted proxies are configured correctly (in bootstrap/app.php for Laravel 11+, or the TrustProxies middleware in earlier versions) to read the real client IP from an X-Forwarded-For header.
Getting the current domain name
$domain = $request->getHost(); // "example.com"
$fullUrl = $request->fullUrl(); // "https://example.com/path?query=value"
$scheme = $request->getScheme(); // "https"
Adding values to the request's input array
$request->merge(['user_id' => auth()->id()]);
// now available through normal input access
$userId = $request->input('user_id');
Merging a value onto the request (rather than passing it as a separate function argument) is a common pattern when a value needs to flow through validation alongside the rest of the request's actual input, as if the client had sent it directly.
Getting the current URL with its query parameters
$request->url(); // current URL without query string
$request->fullUrl(); // current URL including query string
$request->query('sort'); // a specific query parameter's value
Why reaching for these methods beats manually parsing $_SERVER or php://input
Every one of these wraps PHP's underlying superglobals and raw input stream in a consistent, testable interface — in a test, you can construct a Request instance directly with whatever headers, IP, or body you want, something considerably more awkward to fake with raw $_SERVER and php://input access.