您的位置:首页 > 其它

session相关存储扩展

2007-10-18 10:52 239 查看
session相关存储扩展

作者 叁石 sanshi0815
mail sanshi0815@tom.com

对于session的存储,现在解决方案很多,利用最近的时间,完善了,一下。并使用程序实现。
现在使用了一个session的工程类,来控制session的调用跟使用。当前实现的是mysql,
跟memcached的2中存储方式,并解决了memcache扩展没有安装使用php程序调用的可能性。
所以我们先说下memcache的安装问题。
首先下载 memcached 网站是 www.danga.com
解压,然后安装,如果提示缺少libevent 就到他提示的网站去下载安装。
安装完,在回头安装memcached,这个时候,如果安装libevent的时候,指定了,安装目录,那么这个时候会提示一个
so文件找不到,但是去libevent 安装目录下,lib下面是有这个文件的,这个时候,需要做个连接把这个缺少的文件
连接到/usr/lib下也就是说,在系统的默认的加载库中做个连接,让memcache能够找的到。
编译完成,memcached也就安装完成了,然后启动memcached ,去memcached的bin目录下执行,./memcache -h这个命令
如果正式运行就算是启动完毕了,然后根据提示启动memcached的服务
命令如下,请根据自己的实际情况修改 /usr/local/memcache/memcached -d -u root -m 64 -l 192.168.241.195 -p 11211

这个时候,memcached的服务器就算安装完成了

现在我们安装php的扩展
网上有现成的,但是我安装的是时候发现了一些问题。
使用phpize运行下
然后开始编译php的加载模块
运行
解压,进入运行
./configure --enable-memcache --with-php-config=/usr/local/bin/php-config --with-zlib-dir
这个时候提示php-config 找不到

大家要注意了 --with-php-config 这个参数,是要我们告诉他再刚开始编译php的时候,把php放在了那个目录下面
如果我们编译php的时候指定了,就换成那个目录,然后加上php-config 就行了,如果我们编译php的时候,没有指定的话,
那么我们会麻烦些,我们不知道我们的php放在那个目录下面了,那么我们就去php源码下,运行./configure -h这个命令,
看看php默认安装在那里了。
然后继续运行 ./configure --enable-memcache --with-php-config=/usr/local/bin/php-config --with-zlib-dir 这个时候,
如果我们在编译php目录的话,还会提示一个错误,说php-session.h这个文件找不到。这个地方,可就麻烦了,我看了下configure
这个脚本,他里面session_inc_path 这样的一个变量,因为我们编译php的时候没有指定php的存放目录,所以这个.h的文件,不在
这个脚本里尝试判断的文件中,所以我们要手动修改这个脚本,在if完成后,加上一句
session_inc_path="/usr/local/include/php/ext/php_session.h"
当然,是你这个.h文件一定存在的情况下。编译完成,记住最后给你那个目录,然后修改php.ini文件,
修改so文件的加载目录,然后加载so模块,最后重新启动你的apache,然后跑个测试程序如果成功,那么恭喜你,你顺利完成了,
memcache的全部安装。

关于适用范围,我们不多说了,因为现在我们做的这三种存储,一个是文件,一个数据库,一个是memcache,
有着不同的使用范围,这个需要个人去体会了。

现在开始说下程序,为了更加方便的使用这个session的不同的存储机制,我做了一个session的工厂类,来降低耦合性,这样对我们以后的扩展
会有很大的好处。

sessionFartory.class.php
<?php
/**
* base class
* @version  1.0.0
* @author   sanshi0815
* @mail        sanshi0815@tom.com
*/
class sessionFartory
{
function __construct($module_name="")
{
$this->sessionFartory($module_name);
}
function sessionFartory($module_name="")
{
//设置session的有效时间
//$maxLife = get_cfg_var('session.gc_maxlifetime') ? get_cfg_var('session.gc_maxlifetime') : 1440;
if($module_name=="mysql")
{
$this->setSessionObject($module_name);
}else if($module_name=="memcache"){
$this->setSessionObject($module_name);
}else{
}
session_start();
}
function setSessionObject($module_name)
{
//设置sesion模块的名字
//session_module_name(__CLASS__);
$objectName = "{$module_name}Session";
//通过工厂类取得
include_once(dirname(__FILE__)."/factryObject.class.php");
$sesionObject = factryObject::getClass($objectName);
//设置执行的方法
session_set_save_handler
(
array (& $sesionObject, "__open"),
array (& $sesionObject, "__close"),
array (& $sesionObject, "__read"),
array (& $sesionObject, "__write"),
array (& $sesionObject, "__destroy"),
array (& $sesionObject, "__gc")
);
}

}
?>

这段代码并不麻烦,但是有一些潜在的规范

关于/**
* 销毁过期session
*/
function __gc($maxlifetime)
这个方法,我在实际测试的过程中,没有发现这个方法在什么时候调用,如果有知道的请告诉我下

我们现在看看,mysql数据库的存储
mysqlSession.class.php
<?php
/**
* base class
* @version  1.0.0
* @author   sanshi0815
* @mail        sanshi0815@tom.com
*/
include_once(dirname(__FILE__)."/adodbObject.class.php");
class mysqlSession extends adodbObject
{
var $tableName = "session";
var $sessionID = "session_id";
var $tableF = array("session_data","expiry","last_time");
var $dbConfigType = "";
function mysqlSession()
{
//设置session的有效时间
$this->maxLife = get_cfg_var('session.gc_maxlifetime') ? get_cfg_var('session.gc_maxlifetime') : 1440;
}
/**
* 打开session
*/
function __open($save_path, $session_name)
{
$this->adodbObject($this->dbConfigType);
return true;
}
/**
* 关闭session
*/
function __close()
{
return true;
}
/**
* 读取session
*/
function __read($sessionID)
{
//$this->__gc($this->maxLife);
//设置where条件
$where = "{$this->tableF[1]} > '".time()."' AND {$this->sessionID}='{$sessionID}'";
//取得数据
$sql="SELECT * FROM {$this->tableName} WHERE ".$where;
$sessionData = $this->select($sql);
$sessionData = isset($sessionData[0])?$sessionData[0]:"";
$curTime = time();
$expiry = $curTime+$this->maxLife;
//更新session操作时间
$this->update(
$this->tableName,
array(
$this->tableF[0]=>isset($sessionData[$this->tableF[0]])?$sessionData[$this->tableF[0]]:'',
$this->tableF[1]=>$expiry,
$this->tableF[2]=>$curTime
),
$where);
return isset($sessionData[$this->tableF[0]]) ? unserialize($sessionData[$this->tableF[0]]) : false;
}
/**
* 写入session
*/
function __write($sessionID, $sessionData)
{
//设置where条件
$where = "{$this->sessionID}='{$sessionID}'";
//取得数据
$sql="SELECT * FROM {$this->tableName} WHERE ".$where;
$data = $this->select($sql);
$curTime = time();
$expiry = $curTime+$this->maxLife;
if(empty($data))
{
//插入数据
$this->insert(
$this->tableName,
array($this->sessionID=>$sessionID,$this->tableF[0]=>serialize($sessionData),$this->tableF[1]=>$expiry,$this->tableF[2]=>$curTime)
);
}else{
//更新数据
$this->update(
$this->tableName,
array($this->tableF[0]=>serialize($sessionData),$this->tableF[1]=>$expiry,$this->tableF[2]=>$curTime),
$where);
}
}
/**
* 注销session
*/
function __destroy($sessionID)
{
$where = "{$this->sessionID}='{$sessionID}'";
$del = $this->delete($this->tableName,$where);
return $del==1 ? true : false;
}
/**
* 销毁过期session
*/
function __gc($maxlifetime)
{
$where = "{$this->tableF[1]} <= '".time()."'";
return $this->delete($this->tableName,$where);
}
}
?>

下面是对应的sql语句
CREATE TABLE `session` (
`session_id` varchar(32) NOT NULL,
`session_data` mediumtext NOT NULL,
`expiry` varchar(100) NOT NULL,
`last_time` varchar(100) NOT NULL,
KEY `session_id` (`session_id`),
KEY `expiry` (`expiry`),
KEY `last_time` (`last_time`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


这里是可以扩展的,要去修改对应的方法里的设置。
这个也是灵活性,最强的,比如再线统计等等,都能实现

下面是memcache的这个跟php本身的那个文件存储差不多,不可排序,等等,功能都不能实现
memcacheSession.class.php
<?php
/**
* base class
* @version  1.0.0
* @author   sanshi0815
* @mail        sanshi0815@tom.com
*/
include_once(dirname(__FILE__)."/memcacheObject.class.php");
class memcacheSession extends memcacheObject
{
function memcacheSession()
{
//设置session的有效时间
$this->maxLife = get_cfg_var('session.gc_maxlifetime') ? get_cfg_var('session.gc_maxlifetime') : 1440;
}
function __open($save_path, $session_name)
{
$this->memcacheObject();
return true;
}
function __close()
{
$this->close();
return true;
}
/**
* 读取session
*/
function __read($sessionID)
{
$data = $this->get($sessionID);
if(is_array($data))
$this->update($sessionID,$data,$this->maxLife);
return $data;
}
/**
* 写入session
*/
function __write($sessionID, $sessionData)
{
return $this->set($sessionID,$sessionData,$this->maxLife);
}
/**
* 注销session
*/
function __destroy($sessionID)
{
return $this->delete($sessionID);
}
/**
* 销毁过期session
*/
function __gc($sessionID)
{
return true;
}
}
?>

关于memcache的非扩展也扩展的兼容性是在 memcacheObject 里做的
现在我们看下
memcacheObject.class.php
<?php
/**
* base class
* @version  1.0.0
* @author   sanshi0815
* @mail        sanshi0815@tom.com
*/
class memcacheObject
{
var $flag=0;
var $mObject="";
var $isPhp;
function memcacheObject()
{
$this->isPhp = class_exists("Memcache");
if(!$this->isPhp)
{
include_once("MemCachedClient.class.php");
}
return $this->connect();
}
function connect()
{
global $memcacheConfig;
if($this->isPhp)
{
$this->mObject = new Memcache();
$this->mObject->addServer($memcacheConfig['server'],$memcacheConfig['port']);
//$this->mObject->connect($memcacheConfig['server'],$memcacheConfig['port']) or die("Could not connect memcache server!");
}else{
$options["servers"]=array("{$memcacheConfig['server']}:{$memcacheConfig['port']}");
$options["debug"]=false;
$this->mObject = new MemCachedClient($options);
}

}
function set($key,$value,$maxLeft=0)
{
is_object($this->mObject) or $this->connect();
return $this->mObject->set($key,$value,$this->flag,$maxLeft) ? true : false;//die("memcache set valuse is failed");
}
function get($key)
{
is_object($this->mObject) or $this->connect();
return $this->mObject->get($key);
}
function update($key,$value,$maxLeft=0)
{
is_object($this->mObject) or $this->connect();
return $this->mObject->replace($key,$value,$this->flag,$maxLeft) ? true : false;//die("memcache update valuse is failed");
}
function delete($key)
{
is_object($this->mObject) or $this->connect();
return $this->mObject->delete($key,10)  ? true : false;//die("memcache delete valuse is failed");
}
function close()
{
is_object($this->mObject) or $this->connect();
$this->mObject->close();
}
}
?>


现在我们看下测试程序
现在看一个发送session的
<?php
/**
* base class
* @version  1.0.0
* @author   sanshi0815
* @mail        sanshi0815@tom.com
*/
include_once("config/config.inc.php");
include_once("classes/sessionFartory.class.php");
new sessionFartory('memcache');
//new sessionFartory('mysql');
echo $_SESSION['time'] = array("a",'b');
?>

这是一个接受并注销的测试
<?php
/**
* base class
* @version  1.0.0
* @author   sanshi0815
* @mail        sanshi0815@tom.com
*/
include_once("config/config.inc.php");
include_once("classes/sessionFartory.class.php");
new sessionFartory('memcache');
//new sessionFartory('mysql');
print_r($_SESSION);
session_destroy();
print_r($_SESSION);
?>


作者 叁石 sanshi0815
mail sanshi0815@tom.com
转载请著名作者!并说明出处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: