skip to content

On a Laravel RedirectResponse, what do with(), withInput() and withErrors() each put in the session for the next request?

level: middleimportance: should knowfreq 50%

answer

  1. one-request data travelling with a redirect
  2. with(): flash any key, withStatus() magic
  3. withInput(): _old_input, files removed
  4. onlyInput() / exceptInput() filter fields
  5. withErrors(): ViewErrorBag under errors, named bag

basics

~10 s

with() flashes any key and value, withInput() flashes the request input under _old_input without uploaded files, and withErrors() flashes a MessageBag into the errors ViewErrorBag. All three survive only the next request.

solid answer

~40 s

`with('status', 'Review saved')` calls `$session->flash()` for each key, and accepts an array; `withStatus('Review saved')` does the same through `__call`, which snake-cases the name after `with`. `withInput()` flashes the current request's input, or an array you pass, under the `_old_input` key, after removing every uploaded file; `onlyInput('email')` and `exceptInput('password')` filter it. `withErrors($validator)` accepts a `MessageProvider` such as a validator, an array or a string, turns it into a `MessageBag` and stores it inside a `ViewErrorBag` under the `errors` key, in the `default` bag unless you pass a second argument such as `'review'`. All of this is flash data, so the page you redirect to can read it once, through `session('status')`, `old('email')` and `$errors`.

code

php · 21 lines
php
<?php

use App\Models\Book;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class ReviewController
{
    public function store(Request $request, Book $book): RedirectResponse
    {
        if (! $book->isPublished()) {
            return back()
                ->withErrors(['book' => 'Reviews open on publication day.'], 'review')
                ->withInput();
        }

        $review = $book->reviews()->create($request->only('rating', 'body'));

        return to_route('books.show', $book)->withStatus('Thanks, your review is live.');
    }
}

go deeper

for a junior

Know which method carries what: with() for a message, withInput() for the typed values, withErrors() for error messages, all read on the next page.

for a middle

Explain the keys they write (_old_input, errors as a ViewErrorBag), the file stripping, onlyInput and exceptInput, named bags, and the withX() magic.

for a senior

Keep secrets out of flashed input, use named bags when a page has several forms, and keep hand-written redirects consistent with the framework's own validation redirect.

for a principal

Decide how feedback is carried after POSTs across the app, so message keys, bag names and what is never flashed are team conventions rather than per-controller choices.

## Why redirects carry data After a form POST, a Laravel app normally redirects instead of rendering a page (the post-redirect-get pattern). The redirect's target is a fresh GET request, so anything the next page needs, such as a success message, the fields the user typed, or validation errors, has to travel through the session. `Illuminate\Http\RedirectResponse` has three methods for that, and each writes **flash** data: values that are kept for exactly one following request and then discarded. How flash storage ages out is the session's business; what matters here is what each method writes. The running example is a bookshop's **Write a review** form. ## `with()`: any message or value ```php return to_route('books.show', $book)->with('status', 'Thanks, your review is live.'); ``` - `with($key, $value = null)` calls `$session->flash($key, $value)`. - Pass an array to flash several keys: `->with(['status' => 'Saved', 'review_id' => $review->id])`. - **Magic methods:** `RedirectResponse::__call()` turns any unknown method starting with `with` into `with(Str::snake(rest), $argument)`, so `->withStatus('Saved')` flashes `status` and `->withReviewId(7)` flashes `review_id`. - The next page reads it with `session('status')`. ## `withInput()`: what the user typed ```php return back()->withInput()->withErrors(['isbn' => 'We could not find that ISBN.']); ``` - With no argument it takes `$request->input()`; with an array it uses that instead. - It walks the array recursively and **removes every uploaded file**, because file objects cannot sensibly be flashed. - The result is stored with `$session->flashInput()`, which flashes the array under the key `_old_input`. - `onlyInput('email')` and `exceptInput('password', 'card_number')` build the array from `$request->only()` or `$request->except()`, which is how you avoid echoing secrets back into a form. - The next page repopulates fields with `old('title')`; reading old input belongs to request input. ## `withErrors()`: validation-style messages - Accepts a `MessageProvider` (a `Validator`, anything with `getMessageBag()`), an array such as `['isbn' => 'Unknown ISBN']`, or a single string. - Converts it to an `Illuminate\Support\MessageBag`. - Reads the existing `errors` value from the session, or starts a new `Illuminate\Support\ViewErrorBag`, puts the bag under a name, and flashes the whole thing back as `errors`. - The name is the second argument and defaults to `default`: `->withErrors($validator, 'review')` keeps the review form's errors apart from the newsletter form's on the same page. The view side, where `$errors` is shared with every view and read with `@error`, belongs to validation messages. ## Summary table | Method | Session key | Value | Read on the next page with | |---|---|---|---| | `with('status', 'Saved')` | `status` | anything serializable | `session('status')` | | `withStatus('Saved')` | `status` | same, via `__call` | `session('status')` | | `withInput()` | `_old_input` | request input minus files | `old('field')` | | `withErrors($v, 'review')` | `errors` | `ViewErrorBag` with a `review` bag | `$errors->review` | ## Relationship to automatic validation redirects When validation fails on a normal web request, the framework builds this same redirect for you: it goes back to the previous URL, calls `withInput()` with the input minus the `current_password`, `password` and `password_confirmation` fields, and calls `withErrors()` with the validator's messages. Writing it by hand is for checks that are not validation rules, such as "that ISBN is not in our catalogue". ## Common mistakes - **Flashing secrets.** `back()->withInput()` after a failed payment step flashes the card number into the session store. Use `exceptInput('card_number', 'cvc')` or `onlyInput(...)`. - **Expecting uploads to survive.** A cover image chosen before an error is gone after the redirect; tell the user, or store the upload temporarily before redirecting. - **Overwriting instead of adding bags.** Two calls with different bag names both survive, because `withErrors()` reads the existing `ViewErrorBag` first; two calls with the **same** name replace that one bag. - **Flashing large objects.** A whole collection of books passed to `with()` is serialized into the session on every such redirect. Flash an id or a short message and reload the data on the next page. - **Reading the data twice.** Flash data is gone after the next request, so a page that immediately redirects again loses it unless the session keeps it for another request. ## What interviewers probe They want to hear that all three are one-request flash data, the `_old_input` key and the file stripping, and the named error bag. Strong answers mention `exceptInput('password')` and the `withStatus()` magic.

  • What does `->withReviewId(7)` do on a `RedirectResponse`?
    `RedirectResponse::__call()` sees a method starting with `with`, strips that prefix, snake-cases the rest to `review_id`, and calls `with('review_id', 7)`. The value is flashed under `review_id`. A method name that does not start with `with` and is not a registered macro throws `BadMethodCallException`.
  • Why does `withInput()` drop uploaded files, and what does the user see?
    It removes every `UploadedFile` from the input array before flashing, because file objects cannot sensibly be stored in the session. The form comes back with its text fields repopulated through `old()`, but any file input is empty and the user must choose the file again.

saying these in an interview costs you the question

  • with() stores the value in the session permanently until you delete it.
  • withInput() also flashes uploaded files so the form can re-show them.
  • withErrors() only accepts a Validator instance.
  • withErrors() replaces every error bag in the session with the new one.
  • withStatus() is a dedicated method that sets the HTTP status code.