request

Returns the current HTTP request instance, or pulls a single input value out of it.

Signature
request(list<string>|string|null $key = null, mixed $default = null): mixed

Parameters

ParameterTypeDescription
$$keyoptionallist<string>|string|null= nullOmit it to get the request object. A string returns that input value. An array returns only those inputs, skipping any that are absent.
$$defaultoptionalmixed= nullReturned when the resolved value is null. A closure is resolved through value(), so it is only evaluated when needed. Ignored when $key is an array.

Return value

($key is null ? \Illuminate\Http\Request : ($key is string ? mixed : array<string, mixed>))The bound Illuminate\Http\Request when no key is given; the matching input value for a string key; an array of just the present keys for an array of keys.

Errors

Resolving the request out of the container fails outside a booted application, and a console command that was not dispatched from HTTP receives a synthetic request with no user input.

With no arguments, request() resolves the bound Illuminate\Http\Request out of the container, so the whole request API — method(), path(), user(), boolean(), file() — is one call away. With a string it returns a single input value; with an array of strings it returns only those inputs that are actually present.

When to reach for it

  • In Blade templates, where there is nothing to type-hint — marking the active nav item, or re-filling a filter form.
  • In helper functions, view composers, validation rules and static contexts where constructor or method injection is not available.
  • For a one-off read in a closure route that does not otherwise need the object.

In a controller, prefer type-hinting Illuminate\Http\Request: an injected request is visible in the signature and trivial to substitute in a test, while the helper hides the dependency.

What trips people up

A string key goes through the request's __get, which looks in the merged input — query string, body, JSON — and then falls back to route parameters. With implicit model binding, request('post') can therefore hand you a hydrated Post model rather than the string you expected. The default is applied whenever the resolved value is null, so a field submitted empty still triggers it.

Example

Example · php
<?php

// routes/web.php
use Illuminate\Support\Facades\Route;

Route::get('/search', function () {
    echo request('q', 'no query'), PHP_EOL;
    print_r(request(['sort', 'page']));
    echo request()->method(), PHP_EOL;
    echo request()->path(), PHP_EOL;
});

// GET /search?q=laravel&sort=recent
//
// laravel
// Array
// (
//     [sort] => recent
// )
// GET
// search

When to use it

  • Keep the current search term in a Blade filter form with request('q').
  • Highlight the active navigation item by comparing request()->routeIs('orders.*').
  • Read the caller's IP or user agent from a helper class that cannot receive an injected request.
  • Grab a small set of pagination inputs at once with request(['sort', 'page']).

Frequently asked questions

Should I use the helper or type-hint Illuminate\Http\Request?

Type-hint the request in controllers, form requests, jobs and middleware — the dependency is then visible in the signature and easy to swap in a test. Use the helper where injection is impossible: Blade templates, global helper functions, static methods, view composers and custom validation rules.

Does it return route parameters as well as input?

Yes, when you pass a single string key. It reads the merged input first (query string, form body, JSON) and falls back to the route parameter of that name, which under implicit model binding may already be an Eloquent model. Call request()->input('key') if you want input only.

Why does my default get returned when the field was submitted?

Because the default is applied whenever the resolved value is null, not only when the key is missing. Laravel's default global middleware stack includes Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull, so an empty text input arrives as null and therefore does trigger the default, exactly as a null in a JSON body does. Use request()->has('key') to tell a submitted-but-empty field from a missing one, or remove the ConvertEmptyStringsToNull middleware in bootstrap/app.php when you need the empty string itself.

More examples

Re-filling a filter form in Blade

A view has no constructor to inject into, so the helper is the idiomatic way to read input from a template. Note e() around user input: the helper returns raw values, and Blade's {{ }} normally escapes them for you.

Example · php
<?php

// resources/views/orders/index.blade.php
?>
<form method="GET" action="/orders">
    <input type="text" name="q" value="<?php echo e(request('q')); ?>">

    <select name="status">
        <?php foreach (['paid', 'refunded', 'pending'] as $status) { ?>
            <option value="<?php echo $status; ?>"
                <?php echo request('status') === $status ? 'selected' : ''; ?>>
                <?php echo $status; ?>
            </option>
        <?php } ?>
    </select>
</form>
<?php

// GET /orders?q=mug&status=refunded
// -> the text field keeps "mug" and "refunded" stays selected

The route-parameter fallback

This is the difference that surprises people: the one-argument helper reads input first and route parameters second, while input() is restricted to actual user input. Reaching for input() keeps a value that a user submitted separate from a value your own routing produced.

Example · php
<?php

use App\Models\Post;
use Illuminate\Support\Facades\Route;

Route::get('/posts/{post}/edit', function (Post $post) {
    // No input named "post" exists, so __get falls back to the route
    // parameter -- which model binding already resolved to an object.
    var_dump(request('post') instanceof Post);

    // input() never looks at route parameters.
    var_dump(request()->input('post'));

    // The raw route parameter, unambiguously:
    echo request()->route('post')->id, PHP_EOL;
});

// GET /posts/7/edit
// bool(true)
// NULL
// 7

Typed reads and per-request context

A plain service class that is constructed by hand cannot receive an injected request, so the helper supplies the context. boolean() treats "1", "true", "on" and "yes" as true, and integer() casts and falls back — both are safer than comparing raw strings from a form.

Example · php
<?php

// app/Support/AuditLogger.php
class AuditLogger
{
    public function record(string $action): array
    {
        return [
            'action' => $action,
            'user_id' => request()->user()?->id,
            'ip' => request()->ip(),
            'url' => request()->fullUrl(),
            'ajax' => request()->expectsJson(),
            'remember' => request()->boolean('remember'),
            'per_page' => request()->integer('per_page', 25),
        ];
    }
}

print_r((new AuditLogger)->record('order.refunded'));

// Array
// (
//     [action] => order.refunded
//     [user_id] => 3
//     [ip] => 203.0.113.9
//     [url] => https://shop.test/orders/7?tab=refunds
//     [ajax] => 1
//     [remember] => 1
//     [per_page] => 25
// )

Discussion

  • Be the first to comment on this lesson.