在这里我们使用 OO 的方式来实现这些操作,详细代码如下:
define('MY_SESS_TIME',3600); //SESSION 生存时长 //类定义 class My_Sess { /** * 数据库连接对象,设置成了静态变量,因为不设置为静态变量,数据库连接对象在其他方法不能被调用,目前还不清楚什么原因 * * @var obj */ static public $db; /** * 构造函数 * * @param obj $dbname 数据库连接对象 */ function __construct($dbname){ self::$db = $dbname; } /** * 初始化session,使用数据库mysql来存储session的值,利用session_set_save_handler方法实现 * */ function init() { $domain = ''; //不使用 GET/POST 变量方式 ini_set('session.use_trans_sid',0); //设置垃圾回收最大生存时间 ini_set('session.gc_maxlifetime',MY_SESS_TIME); //使用 COOKIE 保存 SESSION ID 的方式 ini_set('session.use_cookies',1); ini_set('session.cookie_path','/'); //多主机共享保存 SESSION ID 的 COOKIE,因为我是本地服务器测试所以设置$domain='' ini_set('session.cookie_domain',$domain); //将 session.save_handler 设置为 user,而不是默认的 files session_module_name('user'); //定义 SESSION 各项操作所对应的方法名 session_set_save_handler( array('My_Sess','open'),//对应于类My_Sess的open()方法,下同。 array('My_Sess','close'), array('My_Sess','read'), array('My_Sess','write'), array('My_Sess','destroy'), array('My_Sess','gc') ); //session_start()必须位于session_set_save_handler方法之后 session_start(); } function open($save_path, $session_name) { //print_r($sesskey); return true; } //end function function close(){ if(self::$db){ self::$db->close(); } return true; } function read($sesskey) { $sql = 'SELECT `data` FROM `sess` WHERE `sesskey`=' . (self::$db->qstr($sesskey)) . ' AND `expiry`>=' . time(); $rs=self::$db->execute($sql); if($rs){ if($rs->EOF){ return ''; } else {//读取到对应于 SESSION ID 的 SESSION 数据 $v = $rs->fields[0]; $rs->close(); return $v; } } return ''; } function write($sesskey,$data){ $qkey = $sesskey; $expiry = time()+MY_SESS_TIME; $arr = array( 'sesskey' => $qkey, 'expiry' => $expiry, 'data' => $data); self::$db->replace('sess', $arr, 'sesskey', true); return true; } function destroy($sesskey) { $sql = 'DELETE FROM `sess` WHERE `sesskey`='.self::$db->qstr($sesskey); $rs =self::$db->execute($sql); return true; } function gc($maxlifetime = null) { $sql = 'DELETE FROM `sess` WHERE `expiry`<'.time(); self::$db->execute($sql); //由于经常性的对表 sess 做删除操作,容易产生碎片, //所以在垃圾回收中对该表进行优化操作。 $sql = 'OPTIMIZE TABLE `sess`'; self::$db->Execute($sql); return true; } } //使用 ADOdb 作为数据库抽象层。 require_once('adodb/adodb.inc.php'); //数据库配置项,可放入配置文件中(如:config.inc.php)。 $db_type = 'mysql'; $db_host = '127.0.0.1'; $db_user = 'root'; $db_pass = '111'; $db_name = 'sess_db'; //创建数据库连接。 $cnn=&ADONewConnection($db_type); $cnn->Connect($db_host,$db_user,$db_pass, $db_name); //初始化 SESSION 设置,初始化时已经包含了session_start()! $sess = new My_Sess($cnn); $sess->init(); $_SESSION['a']='aaa'; $_SESSION['b']='bbb'; $_SESSION['c']='ccc'; print_r($_SESSION); ?> 五、遗留问题 如果网站的访问量很大的话,SESSION 的读写会频繁地对数据库进行操作,这样效率就会明显降低。考虑到 SESSION 数据一般不会很大,可以尝试用 C/Java 写个多线程的程序,用 HASH 表保存 SESSION 数据,并通过 socket 通信进行数据读写,这样 SESSION 就保存在内存中,读写速度应该会快很多。另外还可 以通过负载均衡来分担服务器负载。 最后附上根据上面的实例执行,自己分析的session执行图
![]() |