Cake2系用のが無かったのでCake1系用のこれをforkして作ってみた。
■導入
iRedis
Vendorに配置する
cakephp-redis-session
app/Model/DataSource/Session/に配置する/p>
core.php
core.phpに以下のように記述する。
Configure::write('Session.handler', array('engine' => 'RedisSession'));
Configure::write('RedisSession.hostname', 'some.host.name');
Configure::write('RedisSession.port', 1337);//port
Configure::write('RedisSession.password', 'your password');// password
Configure::write('RedisSession.database', 0);// database number
■コード
オリジナルのコードはパスワードやDB番号が設定できなかったので改良してある。
App::import('Vendor', 'iRedis/iredis');
App::uses('DatabaseSession', 'Model/Datasource/Session');
/**
* Redis Session Store Class
*/
class RedisSession extends DatabaseSession implements CakeSessionHandlerInterface {
private static $store;
private static $timeout;
public function __construct() {
parent::__construct();
$timeout = Configure::read('Session.timeout');
if (empty($timeout)) {
$timeout = 60 * 24 * 90;
}
self::$timeout = $timeout;
}
/**
* open
* connect to Redis
* authorize
* select database
*/
public function open() {
$host = Configure::read('RedisSession.hostname');
$port = Configure::read('RedisSession.port');
$password = Configure::read('RedisSession.password');
$database = Configure::read('RedisSession.database');
if ($host !== null && $port !== null) {
$redis = new iRedisForRedisSession(array('hostname' => $host, 'port' => $port));
}
else {
$redis = new iRedisForRedisSession();
}
if (!empty($password)) {
$redis->auth($password);
}
if (!empty($database)) {
$redis->select($database);
}
self::$store = $redis;
}
/**
* close
* disconnect from Redis
* @return type
*/
public function close() {
self::$store->disconnect();
return true;
}
/**
* read
* @param type $id
* @return type
* - Return whatever is stored in key
*/
public function read($id) {
return self::$store->get($id);
}
/**
* write
* @param type $id
* @param type $data
* @return type
* - SETEX data with timeout calculated in open()
*/
public function write($id, $data) {
self::$store->setex($id, self::$timeout, $data);
return true;
}
/**
* destroy
* @param type $id
* @return type
* - DEL the key from store
*/
public function destroy($id) {
self::$store->del($id);
return true;
}
/**
* gc
* @param type $expires
* @return type
* not needed as SETEX automatically removes itself after timeout
*/
public function gc($expires = null) {
return true;
}
}
if (!class_exists('iRedisForRedisSession')) {
class iRedisForRedisSession extends iRedis {
function __destruct() {
// don't disconnect yet
}
function disconnect() {
parent::__destruct();
}
}
}
iRedisのコードを読んでみると面白いのだがマジックメソッド__callを使って各コマンドをcallしている。