Home » Php » An Elegant Way to Persist Laravel Input Data to the Session

An Elegant Way to Persist Laravel Input Data to the Session

Posted by: admin November 29, 2017 Leave a comment

Questions:

I’m trying to find if there is an elegant way to pass data from the request->input() into the request->session(); . What I’m trying to achieve is to receive user input which I’d like to then reuse in subsequent http requests.

The Ugly Way:

I can do this in an ugly way:

$request->session()->put('name', $request->input('name'));
$request->session()->put('address', $request->input('address'));
$request->session()->put('age', $request->input('age'));
$request->session()->put('bed_time', $request->input('bed_time'));

The Laravelly Way:

But that doesn’t seem very Laravelly, I feel like there should be a way so that I could do something like:

$request->input()->persist();

or

$request->persistInput();

Unfortunately I can’t find anything in the docs that gives me a nicer way to implement this. Is there a way to achieve this? Or am I stuck with this ugly unlaravelly way of persisting data into the session?


Edit :

I’ve accepted Jeff’s answer as the solution to my problem. Which partially details the Laravelly way of approaching this problem.

$request->flash();

Above is the solution on the request that received the input data. However in all subsequent http requests I need to include the following, and access the data like such.

//This makes the data available for the next request.
$request->reflash();

// I can access the data from the last request using the 'old' method.
$name = $request->old('name');
$address = $request->old('address');

I need to reflash everytime I want to pass the data down the line another request.

Answers:

See this manual page. It covers flashing data to session for the next request, which may be what you’re after:

$request->flash();

This will take all of your old input fields and store them in the session’s flash data, keeping them there until the next request. This is useful if, for instance, a user inputs data that does not validate and you wish to redirect with the old data so that you can prepopulate form fields. In fact, there’s an easier way to return both a redirect and flash the same data into session:

return redirect()->back()->withInput();

You can even specify data that you do not want to keep:

return redirect()->back()->withInput($request->except('password'));

Update

Thanks to @Rifki for pointing this out in the comments, but if you would like to keep the data for subsequent HTTP requests and you’re using flash data, then on the next request you can tell the Laravel Session to keep the data for another request:

$request->session()->reflash();

Depending on how long lived this data is, though, you may just want to go ahead and permanently store the data into session. Have a look at the different ways you can retrieve input in this manual entry:

// Store all input
$request->session()->put('some_key', $request->all());
// Store a subset of input
$request->session()->put('some_key', $request->only(['field1', 'field2']));
// Store all except
$request->session()->put('some_key', $request->except('password'));

Questions:
Answers:

You could shorten this down to one line. If you use the except method it will return an array meaning you can do this:

$request->session()->put('request', $request->except('la'))

It will persist the array to the request session key.

I’ve also noticed other answers giving you alternative options. All of these seem to reduce your code base, which is good but I don’t think it’s meeting your ‘Elegance’ criteria.

In my opinion you can shorten your code to give the appearance of ‘elegance’, but in terms of finding the ‘Laravel way’ – to my knowledge there isn’t one.

What you are after is some kind of helper function/class you can use across your App, which will provide the single method elegance you want.

Questions:
Answers:

You are almost there.

If you were to do the following:

session()->put('user', request()->all());

Then the following should be available and persist:

session()->get('user')->name
session()->get('user')->address

Then of course, since we are talking about Laravel, there is a more elegant way of doing it.

You could place the following in a middleware or service provider:

view()->composer('*', function ($view)
{              
    if(session()->has('user')) {
        $view->with('user', session()->get('user'));                
    }
});

Now you can use it like that:

$user->name
$user->address

Questions:
Answers:

What you can do is name your inputs under a namespace

<input name="user[name]">
<input name="user[address]">
<input name="user[age]">
<input name="user[bed_time]">

The in your controller you can call put only once:

$request->session()->put('user', $request->input('user'));

However, if you want to pass the data for the next request only you can do:

return redirect()->route('step.two')->withInput();

This will flash the input to the session.