CakePHP は PHP のネイティヴ session 拡張上に、ユーティリティー機能のスイートとラッパーを提供します。セッションはリクエストにまたがるユニークユーザーの識別と各ユーザーごとの永続的データの格納を可能にします。
セッションの設定は Configure に格納されます。そしてセッションクラスは必要に応じてそこを参照します。セッションの設定はトップレベルの Session キー下に格納され、いくつかのオプションが使用可能です:
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’ 設定のタイムアウトとクッキー名を上書きします。ビルトイン設定は:
セッションハンドラーはセッション 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 クラスを読み込み使用します。
このインターフェースは 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 フラグを微調整することもあります。 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'));
これでアプリケーションはカスタムセッションハンドラーを使ったセッションデータの読み書きを行います。
アプリケーション内のコンテキストにより、セッションへのアクセスを提供するクラスが異なります。コントローラーでは SessionComponent を使用します。ビューでは SessionHelper を使用します。どこからでも使用可能な CakeSession をでセッションにアクセスすることも出来ます。他のインターフェースと同じく、 CakeSession はシンプルな CRUD インターフェースを提供します。
Set::classicExtract() 互換記法を用いてセッションから値を読み込みます:
CakeSession::read('Config.language');
$key はドット区切りで $value の書き込み先を指定します:
CakeSession::write('Config.language', 'eng');
セッションからデータ削除が必要なら削除も可能です:
CakeSession::delete('Config.language');
コントローラーとビューからのセッションデータへのアクセス方法については、合わせて セッション と セッションヘルパー をご覧下さい。