Created
November 15, 2009 18:05
-
-
Save sotarok/235364 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Memcached.php | |
* | |
* @author Sotaro Karasawa <sotaro.k /at/ gmail.com> | |
* @package Ethna | |
* @version $Id$ | |
*/ | |
/** | |
* キャッシュマネージャクラス(pecl::memcached 版) | |
* | |
* @author Sotaro Karasawa <sotaro.k /at/ gmail.com> | |
* @access public | |
* @package Ethna | |
*/ | |
class Ethna_Plugin_Cachemanager_Memcached extends Ethna_Plugin_Cachemanager | |
{ | |
/**#@+ @access private */ | |
/** @var object Memcached Memcached オブジェクト */ | |
private $m = null; | |
/** @var array plugin configure */ | |
public $config_default = array( | |
'host' => 'localhost', | |
'port' => '11211', | |
'use_pconnect' => false, | |
'retry' => 3, | |
'timeout' => 3, | |
); | |
protected $_get_data_cache = array(); | |
/**#@-*/ | |
/** | |
* _load | |
* | |
* @access protected | |
*/ | |
function _load() | |
{ | |
parent::_load(); | |
if ($this->config['use_pconnect']) { | |
$this->m = new Memcached($this->ctl->getAppId()); | |
} | |
else { | |
$this->m = new Memcached(); | |
} | |
if (isset($this->config['servers']) && is_array($this->config['servers'])) { | |
$this->m->addServers($this->config['servers']); | |
} | |
else { | |
$this->m->addServer($this->config['host'], $this->config['port']); | |
} | |
if ($this->config['use_pconnect']) { | |
} | |
} | |
/** | |
* キャッシュに設定された値を取得する | |
* | |
* キャッシュに値が設定されている場合はキャッシュ値 | |
* が戻り値となる。キャッシュに値が無い場合やlifetime | |
* を過ぎている場合、エラーが発生した場合はEthna_Error | |
* オブジェクトが戻り値となる。 | |
* | |
* @access public | |
* @param string $key キャッシュキー | |
* @param int $lifetime キャッシュ有効期間 | |
* @param string $namespace キャッシュネームスペース | |
* @return array キャッシュ値 | |
*/ | |
function get($key, $lifetime = null, $namespace = null) | |
{ | |
$cache_key = $this->_getCacheKey($namespace, $key); | |
if ($cache_key == null) { | |
return Ethna::raiseError('invalid cache key (too long?)', E_CACHE_NO_VALUE); | |
} | |
$value = $this->m->get($cache_key); | |
if (!$value) { | |
return Ethna::raiseError( | |
sprintf('no such cache, key="%s", message="%s"', $key, $this->m->getResultMessage()), | |
E_CACHE_NO_VALUE | |
); | |
} | |
$time = $value['time']; | |
$data = $value['data']; | |
// ライフタイムチェック | |
if ($lifetime !== null) { | |
if (($time + $lifetime) < time()) { | |
return Ethna::raiseError('lifetime expired', E_CACHE_EXPIRED); | |
} | |
} | |
return $data; | |
} | |
/** | |
* キャッシュの最終更新日時を取得する | |
* | |
* @access public | |
* @param string $key cache key | |
* @param string $namespace cache namespace | |
* @return int unixtime | |
*/ | |
function getLastModified($key, $namespace = null) | |
{ | |
$cache_key = $this->_getCacheKey($namespace, $key); | |
if ($cache_key == null) { | |
return Ethna::raiseError('invalid cache key (too long?)', E_CACHE_NO_VALUE); | |
} | |
$value = $this->get($cache_key); | |
if (Ethna::isError($value)) { | |
return $value; | |
} | |
return $value['time']; | |
} | |
/** | |
* 値がキャッシュされているかどうかを取得する | |
* | |
* @access public | |
* @param string $key キャッシュキー | |
* @param int $lifetime キャッシュ有効期間 | |
* @param string $namespace キャッシュネームスペース | |
*/ | |
function isCached($key, $lifetime = null, $namespace = null) | |
{ | |
$r = $this->get($key, $lifetime, $namespace); | |
return Ethna::isError($r) ? false: true; | |
} | |
/** | |
* キャッシュに値を設定する | |
* | |
* @access public | |
* @param string $key キャッシュキー | |
* @param mixed $value キャッシュ値 | |
* @param int $timestamp キャッシュ最終更新時刻(unixtime) | |
* @param string $namespace キャッシュネームスペース | |
* @param int $lifetime expiration | |
*/ | |
function set($key, $value, $timestamp = null, $namespace = null, $expiration = null) | |
{ | |
$cache_key = $this->_getCacheKey($namespace, $key); | |
if ($cache_key === null) { | |
return Ethna::raiseError('invalid cache key (too long?)', E_CACHE_NO_VALUE); | |
} | |
$time = $timestamp ? $timestamp : time(); | |
$expiration = $expiration ? $expiration : 0; | |
if (!$this->m->set($cache_key, array('time' => $time, 'data' => $value), $expiration)) { | |
return Ethna::raiseError( | |
sprintf('failed to set cache, key="%s", message="%s"', $key, $this->m->getResultMessage()), | |
E_CACHE_GENERAL | |
); | |
} | |
return true; | |
} | |
/** | |
* キャッシュ値を削除する | |
* | |
* @access public | |
* @param string $key キャッシュキー | |
* @param string $namespace キャッシュネームスペース | |
*/ | |
public function clear($key, $namespace = null) | |
{ | |
$cache_key = $this->_getCacheKey($namespace, $key); | |
if ($cache_key === null) { | |
return Ethna::raiseError('invalid cache key (too long?)', E_CACHE_NO_VALUE); | |
} | |
if (!$this->m->delete($cache_key)) { | |
return Ethna::raiseError( | |
sprintf('failed to clear cache, key="%s", message="%s"', $key, $this->m->getResultMessage()), | |
E_CACHE_NO_VALUE | |
); | |
} | |
return true; | |
} | |
/** | |
* キャッシュデータをロックする | |
* | |
* @access public | |
* @param string $key キャッシュキー | |
* @param int $timeout ロックタイムアウト | |
* @param string $namespace キャッシュネームスペース | |
* @return bool true:成功 false:失敗 | |
*/ | |
function lock($key, $timeout = 5, $namespace = null) | |
{ | |
// not supported | |
return true; | |
} | |
/** | |
* キャッシュデータのロックを解除する | |
* | |
* @access public | |
* @param string $key キャッシュキー | |
* @param string $namespace キャッシュネームスペース | |
* @return bool true:成功 false:失敗 | |
*/ | |
function unlock($key, $namespace = null) | |
{ | |
// not supported | |
return true; | |
} | |
/** | |
* ネームスペースからキャッシュキーを生成する | |
* | |
* @access private | |
*/ | |
private function _getCacheKey($namespace, $key) | |
{ | |
$namespace = $this->getNamespace($namespace); | |
$key = str_replace(":", "_", $key); | |
$cache_key = $namespace . "::" . $key; | |
if (strlen($cache_key) > 250) { | |
return null; | |
} | |
return $cache_key; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment