Since HTTP driven applications are stateless, sessions provide a way to store information about the user across multiple requests. Laravel ships with a variety of session backends that are accessed through an expressive, unified API. Support for popular backends such as Memcached, Redis, and databases is included out of the box.
The session configuration file is stored at config/session.php
. Be sure to review the options available to you in this file. By default, Laravel is configured to use the file
session driver, which will work well for many applications. In production applications, you may consider using the memcached
or redis
drivers for even faster session performance.
The session driver
configuration option defines where session data will be stored for each request. Laravel ships with several great drivers out of the box:
{tip} The array driver is used during testing and prevents the data stored in the session from being persisted.
When using the database
session driver, you will need to create a table to contain the session items. Below is an example Schema
declaration for the table:
Schema::create('sessions', function ($table) {
$table->string('id')->unique();
$table->integer('user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('payload');
$table->integer('last_activity');
});
You may use the session:table
Artisan command to generate this migration:
php artisan session:table
php artisan migrate
Before using Redis sessions with Laravel, you will need to install the predis/predis
package (~1.0) via Composer. You may configure your Redis connections in the database
configuration file. In the session
configuration file, the connection
option may be used to specify which Redis connection is used by the session.
There are two primary ways of working with session data in Laravel: the global session
helper and via a Request
instance. First, let's look at accessing the session via a Request
instance, which can be type-hinted on a controller method. Remember, controller method dependencies are automatically injected via the Laravel service container:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param Request $request
* @param int $id
* @return Response
*/
public function show(Request $request, $id)
{
$value = $request->session()->get('key');
//
}
}
When you retrieve a value from the session, you may also pass a default value as the second argument to the get
method. This default value will be returned if the specified key does not exist in the session. If you pass a Closure
as the default value to the get
method and the requested key does not exist, the Closure
will be executed and its result returned:
$value = $request->session()->get('key', 'default');
$value = $request->session()->get('key', function() {
return 'default';
});
You may also use the global session
PHP function to retrieve and store data in the session. When the session
helper is called with a single, string argument, it will return the value of that session key. When the helper is called with an array of key / value pairs, those values will be stored in the session:
Route::get('home', function () {
// Retrieve a piece of data from the session...
$value = session('key');
// Specifying a default value...
$value = session('key', 'default');
// Store a piece of data in the session...
session(['key' => 'value']);
});
{tip} There is little practical difference between using the session via an HTTP request instance versus using the global
session
helper. Both methods are testable via theassertSessionHas
method which is available in all of your test cases.
If you would like to retrieve all the data in the session, you may use the all
method:
$data = $request->session()->all();
To determine if a value is present in the session, you may use the has
method. The has
method returns true
if the value is present and is not null
:
if ($request->session()->has('users')) {
//
}
To determine if a value is present in the session, even if its value is null
, you may use the exists
method. The exists
method returns true
if the value is present:
if ($request->session()->exists('users')) {
//
}
To store data in the session, you will typically use the put
method or the session
helper:
// Via a request instance...
$request->session()->put('key', 'value');
// Via the global helper...
session(['key' => 'value']);
The push
method may be used to push a new value onto a session value that is an array. For example, if the user.teams
key contains an array of team names, you may push a new value onto the array like so:
$request->session()->push('user.teams', 'developers');
The pull
method will retrieve and delete an item from the session in a single statement:
$value = $request->session()->pull('key', 'default');
Sometimes you may wish to store items in the session only for the next request. You may do so using the flash
method. Data stored in the session using this method will only be available during the subsequent HTTP request, and then will be deleted. Flash data is primarily useful for short-lived status messages:
$request->session()->flash('status', 'Task was successful!');
If you need to keep your flash data around for several requests, you may use the reflash
method, which will keep all of the flash data for an additional request. If you only need to keep specific flash data, you may use the keep
method:
$request->session()->reflash();
$request->session()->keep(['username', 'email']);
The forget
method will remove a piece of data from the session. If you would like to remove all data from the session, you may use the flush
method:
$request->session()->forget('key');
$request->session()->flush();
Regenerating the session ID is often done in order to prevent malicious users from exploiting a session fixation attack on your application.
Laravel automatically regenerates the session ID during authentication if you are using the built-in LoginController
; however, if you need to manually regenerate the session ID, you may use the regenerate
method.
$request->session()->regenerate();
Your custom session driver should implement the SessionHandlerInterface
. This interface contains just a few simple methods we need to implement. A stubbed MongoDB implementation looks something like this:
<?php
namespace App\Extensions;
class MongoHandler implements SessionHandlerInterface
{
public function open($savePath, $sessionName) {}
public function close() {}
public function read($sessionId) {}
public function write($sessionId, $data) {}
public function destroy($sessionId) {}
public function gc($lifetime) {}
}
{tip} Laravel does not ship with a directory to contain your extensions. You are free to place them anywhere you like. In this example, we have created an
Extensions
directory to house theMongoHandler
.
Since the purpose of these methods is not readily understandable, let's quickly cover what each of the methods do:
Once your driver has been implemented, you are ready to register it with the framework. To add additional drivers to Laravel's session backend, you may use the extend
method on the Session
facade. You should call the extend
method from the boot
method of a service provider. You may do this from the existing AppServiceProvider
or create an entirely new provider:
<?php
namespace App\Providers;
use App\Extensions\MongoSessionStore;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Session::extend('mongo', function($app) {
// Return implementation of SessionHandlerInterface...
return new MongoSessionStore;
});
}
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
Once the session driver has been registered, you may use the mongo
driver in your config/session.php
configuration file.