Laravelの RedirectResponse::with()
のflashが何をやっているのかコードリーディングメモ。
RedirectResponse::with()
は Illuminate\Session\Store::flash()
を呼び出します。
public function with($key, $value = null)
{
$key = is_array($key) ? $key : [$key => $value];
foreach ($key as $k => $v) {
$this->session->flash($k, $v);
}
return $this;
}
https://github.com/laravel/framework/blob/v11.0.7/src/Illuminate/Http/RedirectResponse.php#L35-L51
flash()
では以下のようなことをやっています。
$attributes
プロパティに属性をセット_flash.new
に$key
を追加_flash.old
から$key
を削除
public function flash(string $key, $value = true)
{
$this->put($key, $value);
$this->push('_flash.new', $key);
$this->removeFromOldFlashData([$key]);
}
https://github.com/laravel/framework/blob/v11.0.7/src/Illuminate/Session/Store.php#L443-L450
例えば with(['message' => 'OK'])
という呼び出しをした場合、
key | value |
---|---|
message | OK |
_flash.new | [message] |
_flash.old | [] |
という状態になります。
この Illuminate\Session\Store
は Illuminate\Session\Middleware\StartSession::saveSession()
で save()
メソッドが呼ばれます。
https://github.com/laravel/framework/blob/v11.0.7/src/Illuminate/Session/Middleware/StartSession.php#L245
save()
では以下の処理を行ってます。
_flash.old
に入っているキーの値をセッションストレージから削除_flash.old
に_flash.new
の値(flashのキー配列)をセット_flash.new
の値をクリア$attributes
の値をセッションストレージに格納
public function save()
{
$this->ageFlashData();
$this->prepareErrorBagForSerialization();
$this->handler->write($this->getId(), $this->prepareForStorage(
$this->serialization === 'json' ? json_encode($this->attributes) : serialize($this->attributes)
));
$this->started = false;
}
https://github.com/laravel/framework/blob/v11.0.7/src/Illuminate/Session/Store.php#L166-L177
public function ageFlashData()
{
$this->forget($this->get('_flash.old', []));
$this->put('_flash.old', $this->get('_flash.new', []));
$this->put('_flash.new', []);
}
https://github.com/laravel/framework/blob/v11.0.7/src/Illuminate/Session/Store.php#L218-L225
さきほどの例だと以下のように _flash.new
から _flash.old
に移動していることがわかります。
key | value |
---|---|
message | OK |
_flash.new | [] |
_flash.old | [message] |
この状態でセッションストレージに保存され、次にリクエストしたとき=リダイレクトGETしたときにmessageの値を取得できます。
次にリクエストしたときも同様のミドルウェアの処理で ageFlashData()
が呼ばれます。もしflashの処理やセッションの設定をしていない場合は以下の状態になります。 _flash.old
に格納されていたmessageのキーが削除され、 _flash.new
が _flash.old
に移動して空になっています。
key | value |
---|---|
_flash.new | [] |
_flash.old | [] |
このようにして、リダイレクトGETした1回のみ有効なセッションデータを作り出しています。