@blog.justoneplanet.info

日々勉強

CakePHP 2でRedisにSessionを保持する

Cake2系用のが無かったのでCake1系用のこれをforkして作ってみた。

■導入

iRedis

Vendorに配置する

cakephp-redis-session

app/Model/DataSource/Session/に配置する

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している。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment