webman セッション管理

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        $name = $request->get('name');
        $session = $request->session();
        $session->set('name', $name);
        return response('hello ' . $session->get('name'));
    }
}

$request->session();を使用してWorkerman\Protocols\Http\Sessionインスタンスを取得し、インスタンスのメソッドを使ってセッションデータを追加、変更、削除します。

注意:セッションオブジェクトが破棄されるとき、自動的にセッションデータが保存されるため、$request->session()から返されるオブジェクトをグローバル配列やクラスメンバーに保存し、セッションが保存できなくなることは避けてください。

すべてのセッションデータを取得

$session = $request->session();
$all = $session->all();

返されるのは配列です。セッションデータが存在しない場合、空の配列が返されます。

セッションの特定の値を取得

$session = $request->session();
$name = $session->get('name');

データが存在しない場合はnullが返されます。

getメソッドの第二引数にデフォルト値を渡すこともでき、セッション配列に対応する値が見つからない場合はデフォルト値が返されます。例:

$session = $request->session();
$name = $session->get('name', 'tom');

セッションの保存

特定のデータを保存する際はsetメソッドを使用します。

$session = $request->session();
$session->set('name', 'tom');

setは戻り値を持たず、セッションオブジェクトが破棄されるときにセッションが自動的に保存されます。

複数の値を保存する場合はputメソッドを使用します。

$session = $request->session();
$session->put(['name' => 'tom', 'age' => 12]);

同様に、putも戻り値を持ちません。

セッションデータの削除

特定のセッションデータまたは複数のセッションデータを削除するためにはforgetメソッドを使用します。

$session = $request->session();
// 一項目を削除
$session->forget('name');
// 複数項目を削除
$session->forget(['name', 'age']);

また、システムはdeleteメソッドも提供しており、forgetメソッドとの違いは、deleteは一項目しか削除できません。

$session = $request->session();
// $session->forget('name'); と同じ
$session->delete('name');

セッションの特定の値を取得して削除

$session = $request->session();
$name = $session->pull('name');

以下のコードと同じ効果があります。

$session = $request->session();
$value = $session->get($name);
$session->delete($name);

対応するセッションが存在しない場合はnullが返されます。

すべてのセッションデータを削除

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

戻り値はなく、セッションオブジェクトが破棄されるときにセッションはストレージから自動的に削除されます。

対応するセッションデータが存在するかを判断

$session = $request->session();
$has = $session->has('name');

上記は、対応するセッションが存在しない場合や対応するセッション値がnullである場合はfalseを返し、そうでない場合はtrueを返します。

$session = $request->session();
$has = $session->exists('name');

上記のコードもセッションデータが存在するかを判断するためのものであり、違いは対応するセッション項目の値がnullである場合でもtrueを返すことです。

ヘルパ関数session()

webmanはヘルパ関数session()を提供しており、同じ機能を実現します。

// セッションインスタンスを取得
$session = session();
// 等価
$session = $request->session();

// 特定の値を取得
$value = session('key', 'default');
// 等価
$value = session()->get('key', 'default');
// 等価
$value = $request->session()->get('key', 'default');

// セッションに値を設定
session(['key1'=>'value1', 'key2' => 'value2']);
// 相当する
session()->put(['key1'=>'value1', 'key2' => 'value2']);
// 相当する
$request->session()->put(['key1'=>'value1', 'key2' => 'value2']);

設定ファイル

セッション設定ファイルはconfig/session.phpにあり、内容は以下のようになります。

use Webman\Session\FileSessionHandler;
use Webman\Session\RedisSessionHandler;
use Webman\Session\RedisClusterSessionHandler;

return [
    // FileSessionHandler::class または RedisSessionHandler::class または RedisClusterSessionHandler::class 
    'handler' => FileSessionHandler::class,

    // handlerがFileSessionHandler::classのとき値はfile,
    // handlerがRedisSessionHandler::classのとき値はredis
    // handlerがRedisClusterSessionHandler::classのとき値はredis_cluster(redisクラスター)
    'type'    => 'file',

    // 異なるhandlerに異なる設定を使用
    'config' => [
        // typeがfileのときの設定
        'file' => [
            'save_path' => runtime_path() . '/sessions',
        ],
        // typeがredisのときの設定
        'redis' => [
            'host'      => '127.0.0.1',
            'port'      => 6379,
            'auth'      => '',
            'timeout'   => 2,
            'database'  => '',
            'prefix'    => 'redis_session_',
        ],
        'redis_cluster' => [
            'host'    => ['127.0.0.1:7000', '127.0.0.1:7001', '127.0.0.1:7002'],
            'timeout' => 2,
            'auth'    => '',
            'prefix'  => 'redis_session_',
        ]

    ],

    'session_name' => 'PHPSID', // セッションIDを保存するクッキー名
    'auto_update_timestamp' => false,  // セッションを自動更新するかどうか、デフォルトはオフ
    'lifetime' => 7*24*60*60,          // セッションの有効期限
    'cookie_lifetime' => 365*24*60*60, // セッションIDを保存するクッキーの有効期限
    'cookie_path' => '/',              // セッションIDを保存するクッキーのパス
    'domain' => '',                    // セッションIDを保存するクッキーのドメイン
    'http_only' => true,               // httpOnlyを有効にするかどうか、デフォルトはオン
    'secure' => false,                 // httpsのみにセッションを有効にするかどうか、デフォルトはオフ
    'same_site' => '',                 // CSRF攻撃やユーザー追跡を防ぐために、選択肢はstrict/lax/none
    'gc_probability' => [1, 1000],     // セッションを回収する確率
];

セキュリティ関連

セッションを使用する際は、クラスのインスタンスオブジェクトを直接保存することは推奨されません。特に、制御できないソースからのクラスインスタンスは、逆シリアル化時に潜在的なリスクを引き起こす可能性があります。