喜悦国际村 
» 游客:  注册 | 登录 | 搜索 | 统计 | 喜悦证交所 | 帮助

RSS 订阅当前论坛  

【村长请吃饭啊】 ---北京诚聘--- 【你还在犹豫吗?】

上一主题 下一主题
 12  1/2  1  2  > 
     
标题: [原创] session相关存储扩展  
  本主题由 System 于 2007-11-25 05:00 AM 解除限时高亮 
 
sanshi0815 (sanshi0815)
高级会员
Rank: 4
中级会员



UID 63534
精华 1
积分 533
帖子 669
金钱 523 喜悦币
威望 10
人脉 0
阅读权限 50
注册 2005-3-18
状态 离线
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
转载请著名作者!并说明出处
2007-10-18 10:32 AM#1
查看资料  Blog  发短消息  QQ  顶部
 
八月樱桃
新手上路
Rank: 1


UID 97617
精华 0
积分 8
帖子 19
金钱 8 喜悦币
威望 0
人脉 0
阅读权限 10
注册 2007-8-28
来自 北京
状态 离线
[推荐阅读] 【有挑战的问题】用PHP生成 “图片云图”
刚才就想回复了,怕回的太水太丢人,嘿嘿~~

只想说:

哇塞~~ + 迷糊~~

貌似偶还是沙发???




今天比昨天好,这就是希望……
2007-10-18 10:44 AM#2
查看资料  发短消息  QQ  顶部
 
南极星
乞丐




UID 96781
精华 0
积分 -74
帖子 13
金钱 -74 喜悦币
威望 0
人脉 0
阅读权限 1
注册 2007-8-10
状态 离线
[推荐阅读] PHP使用DOM读取xml时怎么获取标签属性啊
想回复的快 ,不水是不行的 .
2007-10-18 10:46 AM#3
查看资料  发短消息  顶部
 
AK
新手上路
Rank: 1


UID 89896
精华 0
积分 33
帖子 25
金钱 33 喜悦币
威望 0
人脉 0
阅读权限 10
注册 2007-3-22
状态 离线
[推荐阅读] 求助!我配置的红旗linux5.0+apache+mysql+php+discuz验证码的图片出不来
顶一个。努力ing



爱生活,爱AK
欢迎加入我的php唠嗑群15996399
2007-10-18 10:57 AM#4
查看资料  发短消息  QQ  顶部
 
andsky (andsky)
注册会员
Rank: 2
一般会员



UID 63241
精华 0
积分 75
帖子 80
金钱 75 喜悦币
威望 0
人脉 0
阅读权限 20
注册 2005-2-18
状态 离线
[推荐阅读] PHP_curl.dll模块不能加载
好呀,强呀,顶呀,
2007-10-18 12:04 PM#5
查看资料  访问主页  发短消息  顶部
 
qh663
版主
Rank: 7Rank: 7Rank: 7
中级会员


UID 30020
精华 0
积分 546
帖子 580
金钱 546 喜悦币
威望 0
人脉 0
阅读权限 100
注册 2004-7-13
来自 河源
状态 离线
[推荐阅读] 利用zend studio 调试 连不上数据库 怎么回事呀
使用memcache如果不需要放在数据库中。有以下几种方法。
1、也可以修改php.ini配置文件,在php.ini文件只需加入一句:
session.save_handler = memcachesession.save_path = "tcp://127.0.0.1:11211"

2、某个目录下的 .htaccess 加入:
php_value session.save_handler "memcache"php_value session.save_path  "tcp://127.0.0.1:11211"

3、在php代理中加入:
ini_set("session.save_handler", "memcache");ini_set("session.save_path", "tcp://127.0.0.1:11211");

另外,使用多个 memcached server 时用逗号","隔开,类似这样的:"tcp://host1:port1,tcp://host2:port2" 。




五百多篇PHP学习资料
喜悦村BLOG
php团队接兼职项目QQ:80031807
PHP群:768844
2007-10-21 04:53 PM#6
查看资料  访问主页  Blog  发短消息  QQ  顶部
 
nhbbq
新手上路
Rank: 1



UID 85584
精华 0
积分 9
帖子 7
金钱 9 喜悦币
威望 0
人脉 0
阅读权限 10
注册 2007-1-5
状态 离线
[推荐阅读] 一个困了我很久的问题
好东西,留着以后用
2007-10-23 08:48 AM#7
查看资料  发短消息  顶部
 
八月樱桃
新手上路
Rank: 1


UID 97617
精华 0
积分 8
帖子 19
金钱 8 喜悦币
威望 0
人脉 0
阅读权限 10
注册 2007-8-28
来自 北京
状态 离线
[推荐阅读] 上海维西网络科技有限公司(VeryCD)
好东西,留着以后用



今天比昨天好,这就是希望……
2007-10-25 09:19 AM#8
查看资料  发短消息  QQ  顶部
 
奶瓶 (NP博士)
版主
Rank: 7Rank: 7Rank: 7
老仙


UID 52707
精华 4
积分 5282
帖子 5761
金钱 5232 喜悦币
威望 50
人脉 0
阅读权限 100
注册 2004-11-22
来自 北大中文系
状态 在线
[推荐阅读] 论坛与主站整合的的问题
当心你老大生气噢




图片包子,注册送100包子!
2007-10-28 06:55 PM#9
查看资料  访问主页  Blog  发短消息  QQ  ICQ 状态  Yahoo!  顶部
 
jonyare
中级会员
Rank: 3Rank: 3


UID 92705
精华 0
积分 406
帖子 365
金钱 406 喜悦币
威望 0
人脉 0
阅读权限 30
注册 2007-5-8
来自 清华王牌计算机系
状态 离线
[推荐阅读] 三个细节鉴别女人的“质地”
牛人值得顶



务以善小而为之,务以恶小而不为村
2007-10-28 10:26 PM#10
查看资料  Blog  发短消息  顶部
 12  1/2  1  2  > 
     


  可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题 | 开通个人空间  


 


Powered by Discuz! 6.1.0  © 2001-2010 Comsenz Inc.
Processed in 0.035135 second(s), 7 queries

(冀ICP备05009913号) 管理员:sadly 邮箱/MSN: sadly@phpx.com QQ:824008(长隐) 清除 Cookies - - Archiver - WAP