深入Memcache的Session数据的多服务器共享详解

时间:2021-05-18

一相关介绍
1.memcache + memcache的多服务器数据共享的介绍
,请参见http://';//全域cookie域名
private $_cookieName = '_PROJECT_MEMCACHE_SESS';
private $_cookieExpireTime = '';

private $_memServers = array('192.168.0.3' => 11211, '192.168.0.4' => 11211);
private $_sessContainer = array();//当前用户的session信息
private static $_instance = null;//本类单例对象
// }}}


/**
* 单例对象获取的静态方法。
* (可以顺便提供memcache信息存储的服务器参数)
*
* @param string $host - memcache数据存储的服务器ip
* @param integer $port - memcache数据存储的服务器端口号
* @param bool $isInit - 是否实例化对象的时候启动Session
*/
public static function getInstance($host='', $port=11211, $isInit = true) {
if (null === self::$_instance) {
self::$_instance = new self($host, $port, $isInit);
}
return self::$_instance;
}

/**
* 构造函数
*
* @param bool $isInit - 是否实例化对象的时候启动Session
*/
private function __construct($host='', $port=11211, $isInit = false){
!empty($host) && $this->_memServers = array(trim($host) => $port);
$isInit && $this->start();
}

/**
*=-----------------------------------------------------------------------=
*=-----------------------------------------------------------------------=
* Public Methods
*=-----------------------------------------------------------------------=
*=-----------------------------------------------------------------------=
*/

/**
* 启动Session操作
*
* @param int $expireTime - Session失效时间,缺省是0,当浏览器关闭的时候失效, 该值单位是秒
*/
public function start($expireTime = 0){
$_sessId = $_COOKIE[$this->_cookieName];
if (!$_sessId){
$this->_sessId = $this->_getId();
$this->_cookieExpireTime = ($expireTime > 0) ? time() + $expireTime : 0;
setcookie($this->_cookieName, $this->_sessId, $this->_cookieExpireTime, "/", $this->_cookieDomain);
$this->_initMemcacheObj();

$this->_sessContainer = array();
$this->_saveSession();
} else {
$this->_sessId = $_sessId;
$this->_sessContainer = $this->_getSession($_sessId);
}
}

/**
* setSessId
*
* 自定义的session id,通常没有必要经过cookie操作处理的(所以省略了cookie记录session_id)
*
* @param string $sess_id
* @return boolean
*/
public function setSessId($sess_id){
$_sessId = trim($sess_id);
if (!$_sessId){
return false;
} else {
$this->_sessId = $_sessId;
$this->_sessContainer = $this->_getSession($_sessId);
}
}

/**
* 判断某个Session变量是否注册
*
* @param string $varName -
* @return bool 存在返回true, 不存在返回false
*/
public function isRegistered($varName){
if (!isset($this->_sessContainer[$varName])){
return false;
}
return true;
}

/**
* 注册一个Session变量
*
* @param string $varName - 需要注册成Session的变量名
* @param mixed $varValue - 注册成Session变量的值
* @return bool - 该变量名已经存在返回false, 注册成功返回true
*/
public function set($varName, $varValue){
$this->_sessContainer[$varName] = $varValue;
$this->_saveSession();
return true;
}

/**
* 获取一个已注册的Session变量值
*
* @param string $varName - Session变量的名称
* @return mixed - 不存在的变量返回false, 存在变量返回变量值
*/
public function get($varName){
if (!isset($this->_sessContainer[$varName])){
return false;
}
return $this->_sessContainer[$varName];
}

/**
* 销毁一个已注册的Session变量
*
* @param string $varName - 需要销毁的Session变量名
* @return bool 销毁成功返回true
*/
public function delete($varName){
unset($this->_sessContainer[$varName]);
$this->_saveSession();
return true;
}

/**
* 销毁所有已经注册的Session变量
*
* @return 销毁成功返回true
*/
public function destroy(){
$this->_sessContainer = array();
$this->_saveSession();
return true;
}


/**
* 获取所有Session变量
*
* @return array - 返回所有已注册的Session变量值
*/
public function getAll(){
return $this->_sessContainer;
}

/**
* 获取当前的Session ID
*
* @return string 获取的SessionID
*/
public function getSid(){
return $this->_sessId;
}

/**
* 获取Memcache的服务器信息
*
* @return array Memcache配置数组信息
*/
public function getMemServers(){
return $this->_memServers;
}

/**
* 设置Memcache的服务器信息
*
* @param string $host - Memcache服务器的IP
* @param int $port - Memcache服务器的端口
*/
public function setMemServers($arr){
$this->_memServers = $arr;
}

/**
* 添加Memcache服务器
*
* @param string $host - Memcache服务器的IP
* @param int $port - Memcache服务器的端口
*/
public function addMemServer($host, $port){
$this->_memServers[trim($host)] = trim($port);
$this->memObject->addServer($host, $port);
}

/**
* 移除Memcache服务器(注意,这个只是移除配置,并不能实际从memcached的连接池移除)
*
* @param string $host - Memcache服务器的IP
* @param int $port - Memcache服务器的端口
*/
public function removeMemServer($host){
unset($this->_memServers[trim($host)]);
}

/**
*=-----------------------------------------------------------------------=
*=-----------------------------------------------------------------------=
* Private Methods
*=-----------------------------------------------------------------------=
*=-----------------------------------------------------------------------=
*/

/**
* 生成一个Session ID
*
* @return string 返回一个32位的Session ID
*/
private function _getId(){
return md5(uniqid(microtime()));
}

/**
* 获取一个保存在Memcache的Session Key
*
* @param string $_sessId - 是否指定Session ID
* @return string 获取到的Session Key
*/
private function _getSessKey($_sessId = ''){
$sessKey = ($_sessId == '') ? $this->_sessKeyPrefix.$this->_sessId : $this->_sessKeyPrefix.$_sessId;
return $sessKey;
}
/**
* 检查保存Session数据的路径是否存在
*
* @return bool 成功返回true
*/
private function _initMemcacheObj(){
if (!class_exists('Memcache') || !function_exists('memcache_connect')){
$this->_showMessage('Failed: Memcache extension not install, please from http://pecl.php.net download and install');
}
if ($this->memObject && is_object($this->memObject)){
return true;
}
$this->memObject = new Memcache;
if (!empty($this->_memServers)) {
foreach ($this->_memServers as $_host => $_port) {
$this->memObject->addServer($_host, $_port);
}
}

return true;
}

/**
* 获取Session文件中的数据
*
* @param string $_sessId - 需要获取Session数据的SessionId
* @return unknown
*/
private function _getSession($_sessId = ''){
$this->_initMemcacheObj();
$sessKey = $this->_getSessKey($_sessId);
$sessData = $this->memObject->get($sessKey);
if (!is_array($sessData) || empty($sessData)){
//this must be $_COOKIE['__SessHandler'] error!
return array();
}
return $sessData;
}

/**
* 把当前的Session数据保存到Memcache
*
* @param string $_sessId - Session ID
* @return 成功返回true
*/
private function _saveSession($_sessId = ''){
$this->_initMemcacheObj();
$sessKey = $this->_getSessKey($_sessId);

if (empty($this->_sessContainer)){
$ret = @$this->memObject->set($sessKey, $this->_sessContainer, false, $this->_sessExpireTime);
}else{
$ret = @$this->memObject->replace($sessKey, $this->_sessContainer, false, $this->_sessExpireTime);
}

if (!$ret){
$this->_showMessage('Failed: Save sessiont data failed, please check memcache server');
}
return true;
}

/**
* 显示提示信息
*
* @param string $strMessage - 需要显示的信息内容
* @param bool $isFailed - 是否是失败信息, 缺省是true
*/
private function _showMessage($strMessage, $isFailed = true){
return;
if ($isFailed){
echo ($strMessage);
}
echo $strMessage;
}

四应用
1.本地session存储,与原始session操作方式一样,没有任何改变。如:
复制代码 代码如下:
session_start();
$_SESSION['file_session_info']= '本地文件保存的session信息'; //本地文件保存的session

2.memcache共享服务器的session存储
复制代码 代码如下:
$mem= MemcacheSession::getInstance('192.168.0.4', 11211);
$mem->addMemServer('192.168.0.4',11211);
$mem->addMemServer('192.168.0.5',11211);
//如果cookie功能不可用,则根据其他参数传递的唯一信息,设置映射为session_id
if(1) {
$sn= '838ece1033bf7c7468e873e79ba2a3ec';
$mem->setSessId($sn);
}
$mem->set('name','guigui'); //多台memcache服务器共享的session
$mem->set('addr','wuhan'); //多台memcache服务器共享的session
//$mem->destroy();

3.分别获取本地和memcache存储的session信息
复制代码 代码如下:
$addr= $mem->get('addr');
$_MEM_SESSION= $mem->getAll();
echo"<hr>localhost file session:";
var_dump($_SESSION);
echo"<hr>memcache session:";
var_dump($_MEM_SESSION);
//$res= $mem->delete('name');

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章