独自ヘルパ関数追加で階層のあるsessionを作ってみた。


これは何?

Laravelは独自ヘルパ関数を作れます。

今回は、独自ヘルパ関数で、sessionをラップした形のものを作り、
階層つきsessionを作成しました。

どういうとき使うの?

id付きのページ
/hoge/{id}
にアクセスし、これを起点にsessionを保ちながらアクセスせざるを得ない場合使います。

例えば、

/hoge/10
↓
/fuga
↓
/piyo

の遷移

/hoge/20
↓
/fuga
↓
/piyo

の遷移

があるとします。

もし、sessionの値をそれぞれ、
/fuga/piyo
と何かしら使うとしたらどうでしょうか?

今回は下記のようなケースを想定しました。

/hoge/10
↓
/fuga
↓
ここで別タブで
/hoge/20
↓
/fuga
↓
ここで元のタブに戻り
/fuga
↓
/piyo

ここのpiyoのsessionの値は10関連と20関連
どちらでしょうか?
これは20ですよね。10経由にも関わらず別タブで操作した時、sessionを書き換えているため20になります。
この問題を解決したいなぁと思いました。

やり方

どこでも良いですが、自分はHelperディレクトリに作成しました。

app/Helper/HogeSession.php
<?php
if (! function_exists('hoge_session')) {
    /**
     * 多階層セッションの独自ヘルパ関数
     *
     * sessionヘルパ関数を利用して、hogeのセッションをidごとに多階層で管理する
     *
     * 引数がnullだと、現在のhogeセッションをゲット、
     * 引数にarray入れると現在のhogeセッションに値をセット、
     * 引数にstringを入れると現在のhogeセッションからキーに対応する値をゲット
     *
     * @param null|array|string $key
     * @return mixed
     */
    function hoge_session($key = null)
    {
        $hoge_id = session('hoge_id');
        $hoge_session = session('hoge_session') ?? [];

        // 現在のhogeセッションをゲット
        if (is_null($key)) {
            if (array_key_exists($hoge_id, $hoge_session)) {
                return $hoge_session[$hoge_id];
            }
            return $hoge_session;
        }

        // 現在のhogeセッションに値をセット
        if (is_array($key)) {
            if (array_key_exists('hoge_id', $key)) {
                $hoge_id = $key['hoge_id'];
            }
            if (!array_key_exists($hoge_id, $hoge_session)) {
                $hoge_session[$hoge_id] = $key;
            } else {
                foreach ($key as $k => $v) {
                    $hoge_session[$hoge_id][$k] = $v;
                }
            }

            return session([
                'current_hoge_id' => $hoge_id,
                'hoge_session' => $hoge_session,
            ]);
        }

        // 現在のhogeセッションからキーに対応する値をゲット
        return $hoge_session[$hoge_id][$key] ?? null;
    }
}

ファイルをオートローダーで読み込む

composer.json
	"autoload": {
		"classmap": [
          ...
          ..
		],
        ...
        ..
        .
		"files": [
			"app/Helper/HogeSession.php",
		]
	},
$ composer dump-autoload

HogeSession.phpを任意のコントローラーなどで使います。

app/Http/Controllers/HogeController.php

public function fuga(Request $request)
{
    $hoge_id = $request->input('hoge_id');

    // リクエスト確定した段階でhogeセッションのcurrent_hoge_idをリクエスト値に変更
    hoge_session([
       'hoge_id' => $hoge_id ←例えば10だったとする
    ]);

    $test = hoge_session('test');  10に関連する値

    hoge_session([
       'nantoka' => $request->input('nantoka'), ←10に関連する値として更新
       'kantoka' => $request->input('kantoka'), 10に関連する値として更新
    ]);
}

これにて、requestにhoge_idを持たせれば、欲しいsessionの値が取得できます。

/hoge/10
↓
/fuga
↓
ここで別タブで
/hoge/20
↓
/fuga
↓
ここで元のタブに戻り
/fuga
↓
/piyo

上記の場合でもpiyoにて10に関するsessionを取得、更新できるようになりました。