这个类就是实现Session的功能,基本上是通过设置客户端的Cookie来保存SessionID,然后把用户的数据保存在服务器端,最后通过Cookie中的Session Id来确定一个数据是否是用户的,然后进行相应的数据操作。本方式适合Memcache内存方式存储Session数据的方式,同时如果构建分布式的Memcache服务器,能够保存相当多缓存数据,并且适合用户量比较多并发比较大的情况。
<?php /* * 文件: MemcacheSession.inc.php * 类名: MemcacheSession Class * 功能: 自主实现基于Memcache存储的 Session 功能 * 注意: 本类必须要求PHP安装了Memcache扩展或者必须有Memcache的PHP API * 获取Memcache扩展请访问: http://pecl.php.net */ //设定 SESSION 有效时间,单位是 秒 define('SESS_LIFTTIME', 3600); define('DOMAIN', '.jiunile.com'); //定义memcache配置信息 define('MEMCACHE_HOST', 'localhost'); define('MEMCACHE_PORT', '11211'); if (!defined('MemcacheSession')) { define('MemcacheSession', TRUE); class MemacheSession { //类成员属性定义 static $mSessSavePath; static $mSessName; static $mMemcacheObj; /* * 构造函数 * * @param string $login_user 登录用户 * @param int $login_type 用户类型 * @param string $login_sess 登录Session值 * @return Esession */ public function __construct() { //我的memcache是以php模块的方式编译进去的,可以直接调用 //如果没有,就请自己包含 Memcache-client.php 文件 if (!class_exists('Memcache') || !function_exists('memcache_connect')) { die('Fatal Error:Can not load Memcache extension!'); } if (!empty(self::$mMemcacheObj) && is_object(self::$mMemcacheObj)) { return false; } self::$mMemcacheObj = new Memcache; if (!self::$mMemcacheObj->connect(MEMCACHE_HOST , MEMCACHE_PORT)) { die('Fatal Error: Can not connect to memcache host '. MEMCACHE_HOST .':'. MEMCACHE_PORT); } return TRUE; } /* * sessOpen($pSavePath, $name) * @param String $pSavePath * @param String $pSessName * @return Bool TRUE/FALSE */ public function sessOpen($pSavePath = '', $pSessName = '') { self::$mSessSavePath = $pSavePath; self::$mSessName = $pSessName; return TRUE; } /* * sessClose() * @param NULL * @return Bool TRUE/FALSE */ public function sessClose() { return TRUE; } /* * sessRead($wSessId) * @param String $wSessId * @return Bool TRUE/FALSE */ public function sessRead($wSessId = '') { $wData = self::$mMemcacheObj->get($wSessId); //先读数据,如果没有,就初始化一个 if (!empty($wData)) { return $wData; } else { //初始化一条空记录 $ret = self::$mMemcacheObj->set($wSessId, '', 0, SESS_LIFTTIME); if (TRUE != $ret) { die("Fatal Error: Session ID $wSessId init failed!"); return FALSE; } return TRUE; } } /* * sessWrite($wSessId, $wData) * @param String $wSessId * @param String $wData * @return Bool TRUE/FALSE */ public function sessWrite($wSessId = '', $wData = '') { $ret = self::$mMemcacheObj->replace($wSessId, $wData, 0, SESS_LIFTTIME); if (TRUE != $ret) { die("Fatal Error: SessionID $wSessId Save data failed!"); return FALSE; } return TRUE; } /* * sessDestroy($wSessId) * @param String $wSessId * @return Bool TRUE/FALSE */ public function sessDestroy($wSessId = '') { self::sessWrite($wSessId); return FALSE; } /* * sessGc() * @param NULL * @return Bool TRUE/FALSE */ public function sessGc() { //无需额外回收,memcache有自己的过期回收机制 return TRUE; } /* * initSess() * @param NULL * @return Bool TRUE/FALSE */ public function initSess() { //不使用 GET/POST 变量方式 ini_set('session.use_trans_sid', 0); //设置垃圾回收最大生存时间 ini_set('session.gc_maxlifetime', SESS_LIFTTIME); //使用 COOKIE 保存 SESSION ID 的方式 ini_set('session.use_cookies', 1); ini_set('session.cookie_path', '/'); //多主机共享保存 SESSION ID 的 COOKIE ini_set('session.cookie_domain', DOMAIN); //将 session.save_handler 设置为 user,而不是默认的 files session_module_name('user'); //定义 SESSION 各项操作所对应的方法名: session_set_save_handler( array('MemacheSession', 'sessOpen'), //对应于静态方法 My_Sess::open(),下同。 array('MemacheSession', 'sessClose'), array('MemacheSession', 'sessRead'), array('MemacheSession', 'sessWrite'), array('MemacheSession', 'sessDestroy'), array('MemacheSession', 'sessGc') ); session_start(); return TRUE; } } } $memSess = new MemacheSession; $memSess->initSess(); ?>
然后,在项目程序的头文件中直接包含 MemacheSession.inc.php 即可,并且以前的程序不用做任何改动。 测试 创建一个session。
<?php //set_session.php session_start(); if (!isset($_SESSION['admin'])) { $_SESSION['TEST'] = 'wan'; } print $_SESSION['admin']; print "/n"; print session_id(); ?>
用 sessionid 去 memcached 里查询一下
<?php //get_session.php $mem = new Memcache; $mem->connect("127.0.0.1", 11211); var_dump($mem->get('0935216dbc0d721d629f89efb89affa6')); ?>
备注:memcache PECL 未来版本中,可以直接设置 php.ini 来这定自己的 session.save_handler,大致如下:
session.save_handler = memcache session.save_path = "tcp://host:port?persistent=1&weight=2&timeout=2&retry_interval=15,tcp://host2:port2"