イントロダクション
HTTP駆動のアプリケーションはステートレスですから、リクエスト間に渡り情報を保存するセッションが提供されています。Laravelは美しく統一されたAPIを使える様々なバックエンドのセッションを用意しています。人気のあるMemcachedやRedis、データベースも始めからサポートしています。
設定
セッションの設定はconfig/session.php
にあります。このファイルのオプションには詳しくコメントがついていますので確認して下さい。ほとんどのアプリケーションでうまく動作できるように、Laravelはfile
セッションドライバーをデフォルトとして設定しています。実働環境のアプリケーションではセッションの動作をより早くするために、memcached
やredis
ドライバーの使用を考慮しましょう。
セッションドライバー(driver
)はリクエスト毎のセッションデータをどこに保存するかを決めます。Laravelには最初から素晴らしいドライバーが用意されています。
file
- セッションはstorage/framework/sessions
に保存されます。cookie
- セションは暗号化され安全なクッキーに保存されます。database
- セッションはアプリケーションで使用しているデータベースに保存されます。memcached
/redis
- セッションはスピードの早いキャッシュベースの保存域に保存されます。array
- セッションは単にPHPの配列として保存されるだけで、リクエスト間で継続しません。
注意: セッションデータが持続しないように、arrayドライバーは通常テストの実行で使用されます。
ドライバーの事前要件
データベース
database
セッションドライバーを使う場合、セッションアイテムを含むテーブルを準備する必要があります。以下にこのテーブル宣言のサンプル「スキーマ」を示します。
Schema::create('sessions', function ($table) {
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
});
session:table
Artisanコマンドを使えば、このマイグレーションが生成できます!
php artisan session:table
composer dump-autoload
php artisan migrate
Redis
ReidsセッションをLaravelで使用する前に、Composerでpredis/predis
パッケージ(~1.0)をインストールする必要があります。
その他セッションでの考慮点
Laravelフレームワークはflash
セッションキーを内部で使用しているため、この名前でアイテムをセッションに追加してはいけません。
セッションに保存する全データを暗号化したい場合、encrypt
設定オプションをtrue
に指定してください。
基本的な使用法
セッションへのアクセス
最初にセッションへアクセスしてみましょう。コントローラーメソッドでタイプヒントを指定し、HTTPリクエストを経由してセッションをインスタンスへアクセスできます。コントローラーメソッドの依存はLaravelのサービスコンテナにより注入されることを覚えておきましょう。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* 指定ユーザーのプロフィールを表示
*
* @param Request $request
* @param int $id
* @return Response
*/
public function showProfile(Request $request, $id)
{
$value = $request->session()->get('key');
//
}
}
セッションから値を取得するときに、get
メソッドの第2引数としてデフォルト値を渡せます。このデフォルト値は指定したキーがセッションに存在していない場合に返されます。デフォルト値として「クロージャー」をget
メソッドへ渡す場合、その「クロージャー」の実行結果が返されます。
$value = $request->session()->get('key', 'default');
$value = $request->session()->get('key', function() {
return 'default';
});
セッションから全データを取得したい場合は、all
メソッドを使用してください。
$data = $request->session()->all();
セッションから取得したり、保存したりするためにグローバルのsession
ヘルパ関数を使用することができます。
Route::get('home', function () {
// セッションからデータを一つ取得…
$value = session('key');
// セッションへデータ一つを保存…
session(['key' => 'value']);
});
セッション中のアイテム存在を確認
has
メソッドでセッションにアイテムが存在するかを調べられます。このメソッドは存在している場合にtrue
を返します。
if ($request->session()->has('users')) {
//
}
セッションへのデータ保存
セッションインスタンスへアクセスしたら、データを操作するために数々のメソッドを呼び出せます。たとえば新しいデータをセッションへ保存するにはput
を使います。
$request->session()->put('key', 'value');
配列セッション値の追加
push
メソッドは新しい値を配列のセッション値へ追加します。たとえばuser.teams
キーにチーム名の配列が含まれているなら、新しい値を次のように追加できます。
$request->session()->push('user.teams', 'developers');
取得後アイテムを削除
pull
メソッドでセッションからアイテムを取得後、削除できます。
$value = $request->session()->pull('key', 'default');
セッションからアイテムを削除
forget
メソッドでセッションからデータを削除できます。セッションから全データを削除したければ、flush
メソッドが使用できます。
$request->session()->forget('key');
$request->session()->flush();
セッションIDの再生成
セッションIDを再生成する必要がある場合、regenerate
メソッドを使ってください。
$request->session()->regenerate();
フラッシュデータ
次のリクエスト間だけセッションにアイテムを保存したいことは良くあります。flash
メソッドを使ってください。flash
メソッドは直後のHTTPリクエストの間だけセッションにデータを保存します。それ以降は削除されます。フラッシュデータは主にステータスメッセージなど継続しない情報に便利です。
$request->session()->flash('status', 'タスクは成功しました!');
フラッシュデータをさらにその先のリクエストまで持続させたい場合は、reflash
メソッドを使い全フラッシュデータをその先のリクエストまで持続させられます。特定のフラッシュデータのみ持続させたい場合は、keep
メソッドを使います。
$request->session()->reflash();
$request->session()->keep(['username', 'email']);
カスタムセッションドライバーの追加
Laravelのセッションのバックエンドにドライバーを追加したい場合、Session
ファサードのextend
メソッドを使用します。サービスプロバイダーのboot
メソッドからextend
メソッドを呼び出してください。
<?php
namespace App\Providers;
use Session;
use App\Extensions\MongoSessionStore;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
/**
* サービスの初期処理登録後に実行
*
* @return void
*/
public function boot()
{
Session::extend('mongo', function($app) {
// SessionHandlerInterfaceの実装を返す…
return new MongoSessionStore;
});
}
/**
* コンテナに結合を登録
*
* @return void
*/
public function register()
{
//
}
}
カスタムセッションドライバーはSessionHandlerInterface
を実装している点に注意してください。このインターフェイスは実装が必要なシンプルなメソッドで構成されています。MongoDBのスタブ実装は次のようになるでしょう。
<?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) {}
}
キャッシュの「保存インターフェイス」として、これらのメソッドは理解しづらいでしょうから簡単に各メソッドを説明します。
open
メソッドは通常ファイルベースのセッション保存システムで使われます。Laravelはfile
セッションドライバーを用意していますが、皆さんはこのメソッドに何も入れる必要はないでしょう。空のスタブのままで良いでしょう。実際、PHPが実装するように要求しているこのメソッドは、下手なインターフェイスデザインなのです。close
メソッドもopen
と同様に通常は無視できます。ほどんどのドライバーでは必要ありません。read
メソッドは指定された$sessionId
と紐付いたセッションデータの文字列バージョンを返します。取得や保存時にドライバー中でデータをシリアライズしたり、他のエンコード作業を行ったりする必要はありません。Laravelがシリアライズを行います。write
メソッドはMongoDBやDynamoなどの持続可能なストレージに、$sessionId
に紐付け指定した$data
文字列を書き出します。destroy
メソッドは持続可能なストレージから$sessionId
に紐付いたデータを取り除きます。gc
メソッドは指定したUNIXタイムスタンプの$lifetime
よりも古い前セッションデータを削除します。自前で破棄するMemcachedやRedisのようなシステムでは、このメソッドは空のままにしておきます。
セッションドライバーを登録したら、config/session.php
設定ファイルでmongo
ドライバーが使用できます。