本文是 PHP实现多服务器session共享之NFS共享的延续,不过这次,我采用memcache来存储session了,memcache的安装请看这里: 搭建高效、可靠、稳定的WEB服务器 -- 二、) 安装MySQL、memcache。 接下来,再自定义一套session处理机制,关于session的实现方法我
本文是 PHP实现多服务器session共享之NFS共享的延续,不过这次,我采用memcache来存储session了,memcache的安装请看这里: 搭建高效、可靠、稳定的WEB服务器 -- 二、) 安装MySQL、memcache。
接下来,再自定义一套session处理机制,关于session的实现方法我就不再多讲,直接贴程序了。
<?php <br />/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */<br>//===========================================<br>// 程序: Memcache-Based Session Class<br>// 功能: 基于Memcache存储的 Session 功能类<br>// 作者: yejr<br>// 网站: http://imysql.cn<br>// 时间: 2007-01-05<br>//===========================================<br><br>/**<br> * 文件: MemcacheSession.inc.php<br> * 类名: MemcacheSession Class<br> * 功能: 自主实现基于Memcache存储的 Session 功能<br> * 描述: 这个类就是实现Session的功能,基本上是通过<br> * 设置客户端的Cookie来保存SessionID,<br> * 然后把用户的数据保存在服务器端,最后通过<br> * Cookie中的Session Id来确定一个数据是否是用户的,<br> * 然后进行相应的数据操作<br> *<br> * 本方式适合Memcache内存方式存储Session数据的方式,<br> * 同时如果构建分布式的Memcache服务器,<br> * 能够保存相当多缓存数据,并且适合用户量比较多并发比较大的情况<br> *<br> * 注意: 本类必须要求PHP安装了Memcache扩展或者必须有Memcache的PHP API<br> * 获取Memcache扩展请访问: http://pecl.php.net<br> */<br><br>//设定 SESSION 有效时间,单位是 秒<br>define('SESS_LIFTTIME', 3600);<br><br>//定义memcache配置信息<br>define('MEMCACHE_HOST', 'localhost');<br>define('MEMCACHE_PORT', '10000');<br><br>if (!defined('MemcacheSession'))<br>{<br> define('MemcacheSession', TRUE);<br><br>class MemacheSession<br>{<br><br> // {{{ 类成员属性定义<br> static $mSessSavePath;<br> static $mSessName;<br> static $mMemcacheObj;<br> // }}}<br><br> // {{{ 初始化构造函数<br> /**<br> * 构造函数<br> *<br> * @param string $login_user 登录用户<br> * @param int $login_type 用户类型<br> * @param string $login_sess 登录Session值<br> * @return Esession<br> */<br> public function __construct()<br> {<br> //我的memcache是以php模块的方式编译进去的,可以直接调用<br> //如果没有,就请自己包含 Memcache-client.php 文件<br> if (!class_exists('Memcache') || !function_exists('memcache_connect'))<br> {<br> die('Fatal Error:Can not load Memcache extension!');<br> }<br><br> if (!empty(self::$mMemcacheObj) && is_object(self::$mMemcacheObj))<br> {<br> return false;<br> }<br><br> self::$mMemcacheObj = new Memcache;<br><br> if (!self::$mMemcacheObj->connect(MEMCACHE_HOST , MEMCACHE_PORT))<br> {<br> die('Fatal Error: Can not connect to memcache host '. MEMCACHE_HOST .':'. MEMCACHE_PORT);<br> }<br><br> return TRUE;<br> }<br> // }}}<br><br> /** {{{ sessOpen($pSavePath, $name)<br> *<br> * @param String $pSavePath<br> * @param String $pSessName<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function sessOpen($pSavePath = '', $pSessName = '')<br> {<br> self::$mSessSavePath = $pSavePath;<br> self::$mSessName = $pSessName;<br><br> return TRUE;<br> }<br> // }}}<br><br> /** {{{ sessClose()<br> *<br> * @param NULL<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function sessClose()<br> {<br> return TRUE;<br> }<br> // }}}<br><br> /** {{{ sessRead($wSessId)<br> *<br> * @param String $wSessId<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function sessRead($wSessId = '')<br> {<br> $wData = self::$mMemcacheObj->get($wSessId);<br><br> //先读数据,如果没有,就初始化一个<br> if (!empty($wData))<br> {<br> return $wData;<br> }<br> else<br> {<br> //初始化一条空记录<br> $ret = self::$mMemcacheObj->set($wSessId, '', 0, SESS_LIFTTIME);<br><br> if (TRUE != $ret)<br> {<br> die("Fatal Error: Session ID $wSessId init failed!");<br><br> return FALSE;<br> }<br><br> return TRUE;<br> }<br> }<br> // }}}<br><br> /** {{{ sessWrite($wSessId, $wData)<br> *<br> * @param String $wSessId<br> * @param String $wData<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function sessWrite($wSessId = '', $wData = '')<br> {<br> $ret = self::$mMemcacheObj->replace($wSessId, $wData, 0, SESS_LIFTTIME);<br><br> if (TRUE != $ret)<br> {<br> die("Fatal Error: SessionID $wSessId Save data failed!");<br><br> return FALSE;<br> }<br><br> return TRUE;<br> }<br> // }}}<br><br> /** {{{ sessDestroy($wSessId)<br> *<br> * @param String $wSessId<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function sessDestroy($wSessId = '')<br> {<br> self::sessWrite($wSessId);<br><br> return FALSE;<br> }<br> // }}}<br><br> /** {{{ sessGc()<br> *<br> * @param NULL<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function sessGc()<br> {<br> //无需额外回收,memcache有自己的过期回收机制<br><br> return TRUE;<br> }<br> // }}}<br><br> /** {{{ initSess()<br> *<br> * @param NULL<br> *<br> * @return Bool TRUE/FALSE<br> */<br> public function initSess()<br> {<br> $domain = '.imysql.cn';<br><br> //不使用 GET/POST 变量方式<br> ini_set('session.use_trans_sid', 0);<br><br> //设置垃圾回收最大生存时间<br> ini_set('session.gc_maxlifetime', SESS_LIFTTIME);<br><br> //使用 COOKIE 保存 SESSION ID 的方式<br> ini_set('session.use_cookies', 1);<br> ini_set('session.cookie_path', '/');<br><br> //多主机共享保存 SESSION ID 的 COOKIE<br> ini_set('session.cookie_domain', $domain);<br><br> //将 session.save_handler 设置为 user,而不是默认的 files<br> session_module_name('user');<br><br> //定义 SESSION 各项操作所对应的方法名:<br> session_set_save_handler(<br> array('MemacheSession', 'sessOpen'), //对应于静态方法 My_Sess::open(),下同。<br> array('MemacheSession', 'sessClose'),<br> array('MemacheSession', 'sessRead'),<br> array('MemacheSession', 'sessWrite'),<br> array('MemacheSession', 'sessDestroy'),<br> array('MemacheSession', 'sessGc')<br> );<br><br> session_start();<br><br> return TRUE;<br> }<br> // }}}<br><br>}//end class<br><br>}//end define<br><br>$memSess = new MemacheSession;<br>$memSess->initSess();<br>?><br>
然后,在项目程序的头文件中直接包含 MemacheSession.inc.php
即可,并且以前的程序不用做任何改动。
特别感谢:黑夜路人 的 实现基于Memcache存储的Session类。
备注:memcache PECL 未来版本中,可以直接设置 php.ini 来这定自己的 session.save_handler,大致如下:
session.save_handler = memcache<br>session.save_path = "tcp://host:port?persistent=1&weight=2&timeout=2&retry_interval=15,tcp://host2:port2"<br>
详情请见 php_memcache.h cvs log