セッション

CakePHP は PHP のネイティヴ session 拡張上に、ユーティリティー機能のスイートとラッパーを提供します。セッションはリクエストにまたがるユニークユーザーの識別と各ユーザーごとの永続的データの格納を可能にします。

セッションの設定

セッションの設定は Configure に格納されます。そしてセッションクラスは必要に応じてそこを参照します。セッションの設定はトップレベルの Session キー下に格納され、いくつかのオプションが使用可能です:

  • Session.cookie - セッションクッキーの名前を変更します。
  • Session.timeout - CakePHP のセッションハンドラがセッションを破棄するまでの時間を 単位で指定します。この値は下記の Session.autoRegenerate に影響を与えます。これは CakeSession により処理されています。
  • Session.cookieTimeout - 任意のセッション継続時間を 単位で指定します。もしこれが未定義の場合、 Session.timeout の値が使用されます。これは session cookie に影響を与え、PHP 自体により処理されています。
  • Session.checkAgent - ユーザーエージェントはチェックされるべきです。ユーザーエージェントがセッションとマッチしない場合、そのセッションは破棄されます。
  • Session.autoRegenerate - このセッティングを有効にするとセッションとセッション ID の自動更新が有効になります。この値はリクエストの継続的な追跡にセッションの Config.countdown の値を使用します。カウントダウンが 0 になると、セッション ID が再生成されます。これはセキュリティ上の理由でセッション ID を頻繁に変更する場合に有用なオプションです。セッションの再生成が必要なリクエスト数のコントロールは、 CakeSession::$requestCountdown の変更によって可能です。
  • Session.defaults - セッションの設定の基礎としてビルトインのデフォルト設定を使用出来ます。
  • Session.handler - カスタムセッションハンドラーの定義が可能です。コアデータベースとキャッシュセッションハンドラーが使います。このオプションは以前のバージョンの Session.save を置き換えます。詳しくはセッションハンドラーの追加情報をご覧下さい。
  • Session.ini - 追加のセッション ini セッティングを config に加えることが出来ます。これは Session.handler と合わせて以前のバージョンのカスタムセッションハンドリング機能を置き換えます。

CakePHP のデフォルトは、アプリケーションが SSL プロトコル上にある時、 session.cookie_secure が有効 (true) です。SSL と SSL 以外のプロトコルでアプリケーションを動かす場合、セッション消失の問題が発生するかも知れません。SSL と SSL 以外のドメイン両方でセッションにアクセスする必要がある場合、これを無効にします:

Configure::write('Session', array(
    'defaults' => 'php',
    'ini' => array(
        'session.cookie_secure' => false
    )
));

セッションクッキーパスのデフォルト 2.0 において / です。これを変更する場合は session.cookie_path ini フラグにアプリケーションのディレクトリパスを指定することが出来ます:

Configure::write('Session', array(
    'defaults' => 'php',
    'ini' => array(
        'session.cookie_path' => '/app/dir'
    )
));

ビルトインセッションハンドラーと設定

CakePHP にはいくつかビルトインなセッションの設定があります。これらをセッションの設定の基本として使用するか、完全にカスタマイズしたソリューションを作成するかは自由です。デフォルトを使用する場合、単純に ‘defaults’ キーに使用したいデフォルト名をセットします。セッション config で宣言をすればサブセッティングだけを上書きすることも出来ます:

Configure::write('Session', array(
    'defaults' => 'php'
));

上記はビルトインの ‘php’ 設定を使用します。下記のように全てまたは部分的に設定を上書きすることも出来ます:

Configure::write('Session', array(
    'defaults' => 'php',
    'cookie' => 'my_app',
    'timeout' => 4320 //3 days
));

上記は ‘php’ 設定のタイムアウトとクッキー名を上書きします。ビルトイン設定は:

  • php - php.ini ファイルの標準セッティングに沿ってセッションを保存します。
  • cake - セッションをファイルとして app/tmp/sessions に保存します。ホストの設定がホームディレクトリ以外の書き込みを禁止している場合、有効なオプションです。
  • database ビルトインデータベースのセッションを使用します。詳しくは下記をご覧下さい。
  • cache - ビルトインキャッシュのセッションを使用します。詳しくは下記をご覧下さい。

セッションハンドラー

セッションハンドラーはセッション config 配列でも定義出来ます。定義するとセッション保存に使用したいクラスやオブジェクトに様々な session_save_handler の値をマップ可能です。 ‘handler’ の使用には二つの方法があります。一つ目は 5 つの呼び出し可能な (callable) 配列を一つ用意する方法です。これは都度 session_set_save_handler に適用されます:

Configure::write('Session', array(
    'userAgent' => false,
    'cookie' => 'my_cookie',
    'timeout' => 600,
    'handler' => array(
        array('Foo', 'open'),
        array('Foo', 'close'),
        array('Foo', 'read'),
        array('Foo', 'write'),
        array('Foo', 'destroy'),
        array('Foo', 'gc'),
    ),
    'ini' => array(
        'cookie_secure' => 1,
        'use_trans_sid' => 0
    )
));

二つ目の方法は ‘engine’ キーを定義することです。このキーは CakeSessionHandlerInterface を実装するクラス名にするべきです。このインターフェースを実装すると CakeSession がハンドラーのメソッドを自動でマップすることを可能にします。コアのキャッシュとデータベースのセッションハンドラー両方はこのメソッドでセッション保存を行います。ハンドラーの追加セッティングはハンドラーの配列内に設置されるべきです。そうすることでハンドラー内部の外からこれらの値を読み込めるようになります。

またプラグイン内部からセッションハンドラーを使用することも出来ます。エンジンを MyPlugin.PluginSessionHandler といった形で設定します。これはアプリケーションの MyPlugin 内部から PluginSessionHandler クラスを読み込み使用します。

CakeSessionHandlerInterface

このインターフェースは CakePHP 内部の全カスタムセッションハンドラーで使用されます。単純にクラス内にインターフェースを実装し Session.handler.engine を作成したクラス名にセットします。 CakePHP はそのハンドラーを app/Model/Datasource/Session/$classname.php 内部から読み込みます。例えば AppSessionHandler というクラス名なら、app/Model/Datasource/Session/AppSessionHandler.php となります。

データーベースセッション

セッションの設定方法の変更はデータベースセッションの定義の仕方も変更しました。ここではデータベースのデフォルトを選ぶように、ほとんどは設定の中の Session.handler.model をセットするだけです:

Configure::write('Session', array(
    'defaults' => 'database',
    'handler' => array(
        'model' => 'CustomSession'
    )
));

上記は CakeSession にビルトインの ‘database’ 設定を使用するように伝え、 CustomSession というモデルにデータベースへのセッション情報保存の権限を委任よう指定しています。

キャッシュセッション

キャッシュクラスはセッションの格納にも使用されます。これはキャッシュ内のセッションを APC, memcache, または Xcache のように格納することを可能にします。キャッシュセッションの使用ではいくつか注意する点があります。

セッションを元としたキャッシュを使うためセッション config を以下のように設定します:

Configure::write('Session', array(
    'defaults' => 'cache',
    'handler' => array(
        'config' => 'session'
    )
));

これは CakeSession に CacheSession クラスをセッション保存先として委任する設定です。’config’ キーをキャッシュの設定に使用できます。デフォルトのキャッシュ設定は 'default' です。

ini 指示子の設定

デフォルト設定はセッション用に共通の土台を提供します。必要に応じて特定の ini フラグを微調整することもあります。 CakePHP ではデフォルト設定にしろ、カスタム設定にしろ、両者の ini セッティングをカスタマイズ出来ます。セッションセッティングの ini キーで、個別の設定値を指定することが可能です。例えば session.gc_divisor のようなセッティングをコントロールするのに使えます:

Configure::write('Session', array(
    'defaults' => 'php',
    'ini' => array(
        'session.gc_divisor' => 1000,
        'session.cookie_httponly' => true
    )
));

カスタムセッションハンドラーの作成

カスタムセッションハンドラーの作成は CakePHP で容易に出来ます。この例で、セッションをキャッシュ (apc) とデータベースの両方に格納するセッションハンドラーを作成します。これは apc による、キャッシュ限度を超過した際の消失について心配が不要な、最善で高速な IO をもたらします。

まずカスタムクラスを作成し app/Model/Datasource/Session/ComboSession.php として保存する必要があります。クラスは以下のようになります:

App::uses('DatabaseSession', 'Model/Datasource/Session');

class ComboSession extends DatabaseSession implements CakeSessionHandlerInterface {
    public $cacheKey;

    public function __construct() {
        $this->cacheKey = Configure::read('Session.handler.cache');
        parent::__construct();
    }

    // セッションからデータ読み込み
    public function read($id) {
        $result = Cache::read($id, $this->cacheKey);
        if ($result) {
            return $result;
        }
        return parent::read($id);
    }

    // セッションへデータ書き込み
    public function write($id, $data) {
        $result = Cache::write($id, $data, $this->cacheKey);
        if ($result) {
            return parent::write($id, $data);
        }
        return false;
    }

    // セッションの破棄
    public function destroy($id) {
        Cache::delete($id, $this->cacheKey);
        return parent::destroy($id);
    }

    // 期限切れセッションの削除
    public function gc($expires = null) {
        return Cache::gc($this->cacheKey) && parent::gc($expires);
    }
}
    // 期限切れセッションの削除
    public function gc($expires = null) {
        return Cache::gc($this->cacheKey) && parent::gc($expires);
    }
}

このクラスはビルトインの DatabaseSession を継承しそのロジックや振る舞いを重複して定義することを避けています。それぞれのオペレーションを Cache オペレーションでラップします。これで高速なキャッシュからセッションを取得しつつ、キャッシュ限度の考慮を不要にしています。このセッションハンドラーを使うのもまた簡単です。 core.php のセッションブロックを以下のように設定します:

Configure::write('Session', array(
    'defaults' => 'database',
    'handler' => array(
        'engine' => 'ComboSession',
        'model' => 'Session',
        'cache' => 'apc'
    )
));

// apc キャッシュ config を追加すること
Cache::config('apc', array('Engine' => 'Apc'));

これでアプリケーションはカスタムセッションハンドラーを使ったセッションデータの読み書きを行います。

class CakeSession

セッションデータの読み込みと書き込み

アプリケーション内のコンテキストにより、セッションへのアクセスを提供するクラスが異なります。コントローラーでは SessionComponent を使用します。ビューでは SessionHelper を使用します。どこからでも使用可能な CakeSession をでセッションにアクセスすることも出来ます。他のインターフェースと同じく、 CakeSession はシンプルな CRUD インターフェースを提供します。

static CakeSession::read($key)

Set::classicExtract() 互換記法を用いてセッションから値を読み込みます:

CakeSession::read('Config.language');
static CakeSession::write($key, $value)

$key はドット区切りで $value の書き込み先を指定します:

CakeSession::write('Config.language', 'eng');
static CakeSession::delete($key)

セッションからデータ削除が必要なら削除も可能です:

CakeSession::delete('Config.language');

コントローラーとビューからのセッションデータへのアクセス方法については、合わせて セッションセッションヘルパー をご覧下さい。