Skip to content

Instantly share code, notes, and snippets.

@sotarok
Created November 15, 2009 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sotarok/235364 to your computer and use it in GitHub Desktop.
Save sotarok/235364 to your computer and use it in GitHub Desktop.
<?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