这一部分是一个实例,我现在正在用的一个扩展的 Memcache 类,叫 Memcachez,用于多 server 的目的而写,里面还添了点出于自己喜好而使用的风格。使用的方法是填装一个数组形式的 server 群,之后就可以基本照常 add/set/get 了。
类代码如下:
<?PHP
$cfg["cache"] = array(
"192.168.0.8:11211",
"192.168.0.9:11211"
);
$oCache = new Memcachez($cfg["cache"]);
?>
类代码如下:
<?PHP
/*
* MemCacheZ
*
* 多台服务器时自动根据 key 的 crc32 值来选择相应服务器
*
* Zheng Kai 2007-04-29 18:28:10
*/
/*
method:
setCompress (boolean) 是否使用 gzip 压缩(add/set/replace)
setExpire (int) 设置过期时间
add
set
get
replace
increment
decrement
以上这些照常使用
不过注意 add/set/replace 这三个方法的原第三个参数(是否 zlib 压缩)已经省略,
由最后一次 setCompress 来决定;最后一个参数 iExpire 如果为空则沿用 setExpire
的设置,如果都不填,则缺省的默认时间为一小时
*/
class Memcachez {
protected $aLink = array();
protected $aServerList = array();
protected $iServerNumber = 3;
protected $iCompress = 0;
protected $iCompressNow = 0;
protected $iExpire = 3600;
protected $iExpireNow = 3600;
protected $iServerNow = -1;
function __construct($aServerList) {
$this->aServerList = array_values($aServerList);
$this->iServerNumber = count($aServerList);
}
public function setCompress($sSwitch = "") {
if (empty($sSwitch)||(strtolower($sSwitch) == "false")) {
$this->iCompress = 0;
} else {
$this->iCompress = MEMCACHE_COMPRESSED;
}
}
public function setExpire($iExpire) {
$iExpire = intval($iExpire);
if ($iExpire > 1) {
$this->iExpire = $iExpire;
}
}
// 选择 memcached server
protected function _selectServer($sKey, $bServerID = FALSE) {
if ($bServerID) {
$iServerID = intval($sKey);
} else {
$iServerID = sprintf("%u", crc32($sKey)) % $this->iServerNumber;
}
if (($this->iServerNow != $iServerID)&&(!array_key_exists($iServerID, $this->aLink))) {
$this->aLink[$iServerID] = new Memcache();
list($sHost, $iPort) = explode(":", $this->aServerList[$iServerID]);
$this->aLink[$iServerID]->connect($sHost, $iPort);
}
$this->iServerNow = $iServerID;
}
// 选择过期时间
protected function _selectExpire($iExpire) {
$this->iExpireNow = ($iExpire <= 0) ? $this->iExpire : $iExpire;
}
protected function _selectCompress($iCompress) {
$this->iExpireNow = ($iCompress <= 0) ? $this->iCompressNow : $iCompress;
}
// add
public function add($sKey, $sValue, $iExpire = 0, $iCompress = 0) {
$this->_selectServer($sKey);
$this->_selectExpire($iExpire);
$this->_selectCompress($iCompress);
return $this->aLink[$this->iServerNow]->add($sKey, $sValue, $this->iCompressNow, $this->iExpireNow);
}
// set
public function set($sKey, $sValue, $iExpire = 0, $iCompress = 0) {
$this->_selectServer($sKey);
$this->_selectExpire($iExpire);
$this->_selectCompress($iCompress);
return $this->aLink[$this->iServerNow]->set($sKey, $sValue, $this->iCompressNow, $this->iExpireNow);
}
// replace
public function replace($sKey, $sValue, $iExpire = 0, $iCompress = 0) {
$this->_selectServer($sKey);
$this->_selectExpire($iExpire);
$this->_selectCompress($iCompress);
return $this->aLink[$this->iServerNow]->replace($sKey, $sValue, $this->iCompressNow, $this->iExpireNow);
}
// get
public function get($sKey) {
$this->_selectServer($sKey);
return $this->aLink[$this->iServerNow]->get($sKey);
}
// delete
public function delete($sKey, $iTimeout = 0) {
$this->_selectServer($sKey);
return $this->aLink[$this->iServerNow]->delete($sKey, $iTimeout);
}
// increment
public function increment($sKey, $iValue) {
$this->_selectServer($sKey);
return $this->aLink[$this->iServerNow]->increment($sKey, $iValue);
}
// decrement
public function decrement($sKey, $iValue) {
$this->_selectServer($sKey);
return $this->aLink[$this->iServerNow]->decrement($sKey, $iValue);
}
// getStats
public function getStats() {
$aStats = array();
foreach ($this->aServerList as $iKey => $sValue) {
$this->_selectServer($iKey, TRUE);
$aStats[$sValue] = $this->aLink[$iKey]->getStats();
}
return $aStats;
}
// flush
public function flush() {
foreach ($this->aServerList as $iKey => $sValue) {
$this->_selectServer($iKey, TRUE);
$this->aLink[$iKey]->flush();
}
}
}
?>