php实现session入库

来源:互联网 发布:网络银行的交易额 编辑:程序博客网 时间:2024/04/30 13:35

为什么要把session存入数据库?有什么用?

可以:统计在线人数,现实多站点session共享(通行证),控制同个账号登入人数等。

要实现session的入库,有关键的几个基本知识:

session.gc_divisor = 100  session.gc_probability = 1 。session.gc_probability 与 session.gc_divisor 合起来用来管理 gc(garbage collection 垃圾回收)进程启动的概率。( session.gc_probability/session.gc_divisor = 概率)

session.gc_maxlifetime = 1024 。session.gc_maxlifetime 指定过了多少秒之后数据就会被视为“垃圾”并被清除。

session.save_handler = files 。session.save_handler 定义了来存储和获取与会话关联的数据的处理器的名字。默认为 files。参见 session_set_save_handler()。

首先设计数据库表:

CREATE TABLE IF NOT EXISTS `session` (  `phpsession` char(32) COLLATE utf8_bin NOT NULL,  `uptime` int(10) unsigned NOT NULL,  `data` text COLLATE utf8_bin NOT NULL,  PRIMARY KEY (`phpsession`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

可根据需求增加相应的字段。这里为演示方便,就设置基本的字段。

需要2个class, 一个是数据库的,一个是session的操作类

<?php/** * session入库操作类 * @author 删代码工程师  geek-cy.com */include 'DbSession.php'; //引入session数据库操作类class MySession extends DbSession{private $dbc = null; //保存数据库资源句柄private $lifetime = null; // session的生成时间private $time = null; //当前时间const uptime = 30; //更新session的时间static $DEBUG = false; //是否开启错误提示public function __construct(  ){$this->init();$this->SessionSetSaveHandler();}/** * 初始化session处理 * @throws Exception */private function init(){try{//设置数据库链接资源句柄$db = DbSession::InitDbSession(); //获取用于数据库操作的对象if( !($db instanceof DbSession) ){throw new Exception('需要MySession类的对象');}else{$this->dbc = $db;}//设置session有效时间if( !$this->lifetime = ini_get('session.gc_maxlifetime') ){throw new Exception('session.gc_maxlifetime获取失败');}}catch (Exception $e){$this->ShowErrow( $e->getMessage() );}$this->time = time();// ini_set('session.save_handler', user);}/** * 设置自定义session的回调方法 */private function SessionSetSaveHandler(){session_set_save_handler(array($this, "open"),array($this, "close"),array($this, "read"),array($this, "write"),array($this, "destroy"),array($this, "gc"));session_start();//开启session}/** * 打开session * @param string $savePath * @param string $sessName * @return boolean */public function open($savePath, $sessName){if(is_null( $this->dbc )){ //判断数据库连接是否正常return false;}else{return true;}}/** * 关闭session */public function close(){$this->gc($this->lifetime); //触发垃圾回收机制return $this->dbc->MysqlClose(); //关闭数据库连接}/** * 读取session * @param string $sessionid * @return boolean|unknown */public  function read( $sessionid ){$selectData = array(0=>$this->phpsession,1=>$this->uptime,2=>$this->data); // 需要读取的字段,数组形式$sessionData = $this->dbc->ReadSession($sessionid, $selectData);//是否返回有效值if( $sessionData == false){return false;}//是否过期判断if( $sessionData[$this->uptime] + $this->lifetime < $this->time ){$this->destroy( $sessionData[$this->phpsession] );return false;}return $sessionData[$this->data];}/** * 写入session * @param string $sessionid * @param string $data * @return boolean */public function write( $sessionid, $data ){$selectData = array(0=>$this->phpsession,1=>$this->uptime,2=>$this->data);// 需要读取的字段,数组形式$sessionData = $this->dbc->ReadSession($sessionid, $selectData);if( $sessionData == false){ //没有session数据if( !empty( $data ) ){ //判断是否用需要插入的session值//数组形式组装要插入的字段和对应值$insertData = array($this->phpsession => $sessionid,$this->uptime => $this->time,$this->data=> $data);$this->dbc->InsertSession( $insertData );}}else{//已经有了session数据//判断session数据是否有改变,或者需要更新有效时间。 if($sessionData[$this->data] != $data || $this->time > ($sessionData[$this->uptime]+self::uptime)){//以数组形式组装要更新的数据$updateData = array($this->uptime => $this->time,$this->data=> $data);$this->dbc->UpdateSession($sessionData[$this->phpsession], $updateData );}}return true;}/** * 销毁session * @param string $sessionid */public  function destroy( $sessionid ){return $this->dbc->DeleteSession( $sessionid );}/** * session的回收机制 * @param string $lifetime */public function gc( $lifetime ){$this->dbc->GcSession( $lifetime );}}?>

<?php/** * session入库的数据库操作类 * @author 删代码工程师  geek-cy.com * */class DbSession{public static $db = null;private $con = null; //保存数据库链接资源句柄private $HOSTNAME = 'localhost'; private $DB = 'phptest';private $USER = 'root';private $PASSWORD = '';const CHARSET = 'UTF8'; //编码设置static $DEBUG = true; //是否开启错误提示//session表与表字段private $TableName = 'session'; protected $phpsession = 'phpsession'; protected $uptime = 'uptime';protected $data = 'data'; private function __construct(){$this->contect();}private function __clone(){}/** * 初始化链接数据库 * @return Ambigous <NULL, string> */public static function InitDbSession(){if( is_null(self::$db) || !(self::$db instanceof self) ){self::$db = new DbSession;}return self::$db; //返回类对象}/** * 链接数据库 *  */private  function contect(){$this->con = mysql_connect($this->HOSTNAME, $this->USER, $this->PASSWORD); //保存数据库连接资源句柄try{if( is_null($this->con) ){throw new Exception('链接数据库失败');}if(!mysql_select_db($this->DB, $this->con)){throw new Exception('选择数据库失败');}mysql_query("SET NAMES self::CHARSET");}catch (Exception $e){$this->ShowErrow( $e->getMessage() );}}/** * 输出错误 * @param string $msg */protected function ShowErrow( $msg ){if(static::$DEBUG){ //判断是否打印错误echo $msg;}}/** * 读取数据库中保存的session * @param string $sessionid * @param array $selectData * @return boolean|Ambigous <boolean, multitype:> */public function ReadSession( $sessionid, array $selectData ){$selectData = $this->doSelectData($selectData);if(!$selectData){return false;}if( $this->CheckSessionId($sessionid) ){$sql = 'SELECT '.$selectData.' FROM `'.$this->TableName.'` WHERE '.$this->phpsession.' = \''.$sessionid.'\' LIMIT 1';$result = mysql_query($sql, $this->con);return $this->fetch($result);}}/** * 写入新session到数据库中 * @param array $insertData * @return boolean */public function InsertSession( array $insertData ){if( $insertData = $this->doInsertData($insertData) ){$sql = 'INSERT INTO '.$this->TableName.'('.$insertData[0].') VALUES('.$insertData[1].')';mysql_query($sql, $this->con);return true;}else{return false;}}/** * 更新数据库中保存的session * @param string $sessionid * @param array $updateData * @return boolean */public function UpdateSession( $sessionid, array $updateData){if( !$this->CheckSessionId($sessionid) ){return false;}if( $updateData = $this->doUpadateData($updateData) ){$sql = 'UPDATE '.$this->TableName.' SET '.$updateData.' WHERE '.$this->phpsession.' = \''.$sessionid.'\'';mysql_query($sql, $this->con);return true;}else{return false;}}/** * 删除数据库中的session * @param string $sessionid * @return boolean */public function DeleteSession( $sessionid ){if( !$this->CheckSessionId($sessionid) ){return false;}$sql = 'DELETE FROM '.$this->TableName.' WHERE \''.$sessionid.'\' = '.$this->phpsession;mysql_query($sql,$this->con);return true;}/** * 回收清除数据库中已经获取无用的session * @param string $lifetime * @return boolean */public function GcSession( $lifetime ){if( !ctype_digit($lifetime )){return false;}$checktime = time()-$lifetime;$sql = 'DELETE FROM '.$this->TableName.' WHERE '.$this->uptime.' < '.$checktime ;mysql_query($sql,$this->con);return true;}/** * 关闭数据库连接 */public function MysqlClose(){mysql_close( $this->con );}public function __destruct(){self::$db = null;if($this->con instanceof self){mysql_close( $this->con );}}/** * 对session id 做合法性检查 * @param string $sessionid * @return boolean */private function CheckSessionId( $sessionid ){return ctype_alnum($sessionid);}/** * 返回select取得的结果集 * @param  $result * @return boolean|multitype: */private function fetch(  $result ){if( $result && mysql_num_rows($result) == 1){$resultArray = array();$resultArray = mysql_fetch_array($result, MYSQL_ASSOC);if( !$resultArray || count($resultArray)== 0 ){return false;}else{return $resultArray;}}else{return false;}}/** * 处理select要查询的字段 * @param array $data * @return boolean|string */private function doSelectData( array $data ){$keyString = '';foreach ($data as $value){$keyString .= '`'.$value.'`,';}$keyString  =  substr($keyString,0,-1);if($keyString == ''){return false;}return $keyString;}/** * 处理要insert进数据库的字段和对应的值 * @param array $data * @return boolean|string */private function doInsertData( array $data ){$keyString = '';$valueString = '';if(array_key_exists($this->phpsession, $data)){if( !$this->CheckSessionId($data[$this->phpsession]) ){return false;}}foreach ($data as $key => $value){$keyString .= '`'.$key.'`,';if(ctype_digit($value)){$valueString .= ''.$value.',';}else{$valueString .= '\''.$value.'\',';}}if( $keyString != '' && $valueString != ''){$keyString  =  substr($keyString,0,-1);$valueString =  substr($valueString,0,-1);$dataArray[0] = $keyString; //字段$dataArray[1] = $valueString;//值return $dataArray;}else{return false;}}/** * 处理update的字段和对应的值 * @param array $data * @return boolean|string */private function doUpadateData( array $data ){$upDataString = '';foreach($data as $key => $value){if(ctype_digit($value)){$value = ''.$value.'';}else{$value = '\''.$value.'\'';}$upDataString .= '`'.$key.'` = '.$value.',';}$upDataString = substr($upDataString,0,-1);if( $upDataString == ''){return false;}return $upDataString;}}

下面是使用方法:

<?php include 'MySession.php';$session = new MySession( );$_SESSION['test1'] = 'test1';$_SESSION['test2'] = 2;$_SESSION['test3'] = array(1,2,3,4);// session_destroy();?>

更多:geek-cy

0 0
原创粉丝点击