ITCakePHPRedisPHP

cakePHPでRedisにCacheするコマンドを追加拡張する

cakephpではRedisをサポートしているため、導入すれば、getコマンド、setコマンドが使用できます。 しかし、初期状態ではmsetなどのコマンドは用意されておらず、このままでは、せっかくのRedisのパフォーマンスを生かすことができないため、使用できるコマンドを追加する方法をご紹介します。

追加の流れ

追加…とはいっても、実際にはphpredisに登録されているコマンドをcakePHPから呼び出す流れまでです。 Cache::write()コマンドを実行したときには、 プロジェクト/lib/Cake/Cache/Cache.phpのwriteメソッドが呼び出されます。 そして、Cache::writeの第三引数とbootstrap.phpに登録したキャッシュエンジン名が一致している部分で登録しているエンジンが呼び出されます。 私の場合は、bootstrap.phpに

Cache::config('redis', array(
   'engine'      => 'Redis',
   'server'      => '127.0.0.1',
   'port'    => 6379,
));

と書いているため、第三引数で’redis’を指定しています。 Cache.phpのwriteメソッドでは、各エンジンのwriteメソッドが呼び出されるようになっていますので、ここではRedisEngine.phpのwriteメソッドが呼び出されます。 (PATH:プロジェクト/lib/Cake/Cache/Engine/RedisEngine.php)

public function write($key, $value, $duration) {
		if (!is_int($value)) {
			$value = serialize($value);
		}
		if (!$this->_Redis->isConnected()) {
			$this->_connect();
		}
		if ($duration === 0) {
			return $this->_Redis->set($key, $value);
		}
		return $this->_Redis->setex($key, $duration, $value);
	}

ここに記述されている

$this->_Redis->set($key, $value);
$this->_Redis->setex($key, $duration, $value);

の二つがphpredisの呼び出し場所です。 writeメソッドでは、bootstrap.phpにdurationで有効期限を設定した場合には、setexを呼びだし、設定されていない場合にはsetを呼び出すように設定してあるようです。

実装してみよう

今回は練習としてkeysコマンドを実装します。 keysコマンドとは… 正規表現を使用し、登録されたキー一覧を取得することができるコマンドです。 Cache.php

public static function keys($key, $config = 'default') {
		$settings = self::settings($config);
		if (empty($settings)) {
			return false;
		}
		if (!self::isInitialized($config)) {
			return false;
		}
		if (!$key) {
			return false;
		}
		return self::$_engines[$config]->readRegex($settings['prefix'] . $key);
}

RedisEngine.php

public function readRegex($key) {
		$value = $this->_Redis->keys($key);
		if (ctype_digit($value)) {
			$value = (int)$value;
		}
		if ($value !== false && is_string($value)) {
			$value = unserialize($value);
		}
		return $value;
}

を追記すれば実装完了です。 呼び出す場合には、

Cache::keys('*');

などと書けば取得することができます。