session相关存储扩展

来源:互联网 发布:出纳软件哪个好 编辑:程序博客网 时间:2024/06/05 07:10

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
[code]
<?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")
  );
 }

}
?>
[/code]
这段代码并不麻烦,但是有一些潜在的规范

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

我们现在看看,mysql数据库的存储
mysqlSession.class.php
[code]
<?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);
 }
}
?>
[/code]
下面是对应的sql语句
[code]
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;
[/code]

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

下面是memcache的这个跟php本身的那个文件存储差不多,不可排序,等等,功能都不能实现
memcacheSession.class.php
[code]
<?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;
 }
}
?>
[/code]
关于memcache的非扩展也扩展的兼容性是在 memcacheObject 里做的
现在我们看下
memcacheObject.class.php
[code]
<?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();
 }
}
?>
[/code]

现在我们看下测试程序
现在看一个发送session的
[code]
<?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');
?>
[/code]
这是一个接受并注销的测试
[code]
<?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);
?>
[/code]

作者 叁石  sanshi0815
mail sanshi0815@tom.com
转载请著名作者!并说明出处