为什么要把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()

首先设计数据库表:

 [sql] 

  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的操作类

  1. <?php
  2. /**
  3. * session入库操作类
  4. * @author 删代码工程师  geek-cy.com
  5. */
  6. include 'DbSession.php'; //引入session数据库操作类
  7. class MySession extends DbSession{
  8. private $dbc = null; //保存数据库资源句柄
  9. private $lifetime = null; // session的生成时间
  10. private $time = null; //当前时间
  11. const uptime = 30; //更新session的时间
  12. static $DEBUG = false; //是否开启错误提示
  13. public function __construct(  ){
  14. $this->init();
  15. $this->SessionSetSaveHandler();
  16. }
  17. /**
  18. * 初始化session处理
  19. * @throws Exception
  20. */
  21. private function init(){
  22. try{
  23. //设置数据库链接资源句柄
  24. $db = DbSession::InitDbSession(); //获取用于数据库操作的对象
  25. if( !($db instanceof DbSession) ){
  26. throw new Exception('需要MySession类的对象');
  27. }else{
  28. $this->dbc = $db;
  29. }
  30. //设置session有效时间
  31. if( !$this->lifetime = ini_get('session.gc_maxlifetime') ){
  32. throw new Exception('session.gc_maxlifetime获取失败');
  33. }
  34. }catch (Exception $e){
  35. $this->ShowErrow( $e->getMessage() );
  36. }
  37. $this->time = time();
  38. //      ini_set('session.save_handler', user);
  39. }
  40. /**
  41. * 设置自定义session的回调方法
  42. */
  43. private function SessionSetSaveHandler(){
  44. session_set_save_handler(
  45. array($this, "open"),
  46. array($this, "close"),
  47. array($this, "read"),
  48. array($this, "write"),
  49. array($this, "destroy"),
  50. array($this, "gc")
  51. );
  52. session_start();//开启session
  53. }
  54. /**
  55. * 打开session
  56. * @param string $savePath
  57. * @param string $sessName
  58. * @return boolean
  59. */
  60. public function open($savePath, $sessName){
  61. if(is_null( $this->dbc )){ //判断数据库连接是否正常
  62. return false;
  63. }else{
  64. return true;
  65. }
  66. }
  67. /**
  68. * 关闭session
  69. */
  70. public function close(){
  71. $this->gc($this->lifetime); //触发垃圾回收机制
  72. return $this->dbc->MysqlClose(); //关闭数据库连接
  73. }
  74. /**
  75. * 读取session
  76. * @param string $sessionid
  77. * @return boolean|unknown
  78. */
  79. public  function read( $sessionid ){
  80. $selectData = array(0=>$this->phpsession,1=>$this->uptime,2=>$this->data); // 需要读取的字段,数组形式
  81. $sessionData = $this->dbc->ReadSession($sessionid, $selectData);
  82. //是否返回有效值
  83. if( $sessionData == false){
  84. return false;
  85. }
  86. //是否过期判断
  87. if( $sessionData[$this->uptime] + $this->lifetime < $this->time ){
  88. $this->destroy( $sessionData[$this->phpsession] );
  89. return false;
  90. }
  91. return $sessionData[$this->data];
  92. }
  93. /**
  94. * 写入session
  95. * @param string $sessionid
  96. * @param string $data
  97. * @return boolean
  98. */
  99. public function write( $sessionid, $data ){
  100. $selectData = array(0=>$this->phpsession,1=>$this->uptime,2=>$this->data);// 需要读取的字段,数组形式
  101. $sessionData = $this->dbc->ReadSession($sessionid, $selectData);
  102. if( $sessionData == false){ //没有session数据
  103. if( !empty( $data ) ){ //判断是否用需要插入的session值
  104. //数组形式组装要插入的字段和对应值
  105. $insertData = array(
  106. $this->phpsession    => $sessionid,
  107. $this->uptime        => $this->time,
  108. $this->data          => $data
  109. );
  110. $this->dbc->InsertSession( $insertData );
  111. }
  112. }else{//已经有了session数据
  113. //判断session数据是否有改变,或者需要更新有效时间。
  114. if($sessionData[$this->data] != $data || $this->time > ($sessionData[$this->uptime]+self::uptime)){
  115. //以数组形式组装要更新的数据
  116. $updateData = array(
  117. $this->uptime    => $this->time,
  118. $this->data      => $data
  119. );
  120. $this->dbc->UpdateSession($sessionData[$this->phpsession], $updateData );
  121. }
  122. }
  123. return true;
  124. }
  125. /**
  126. * 销毁session
  127. * @param string $sessionid
  128. */
  129. public  function destroy( $sessionid ){
  130. return $this->dbc->DeleteSession( $sessionid );
  131. }
  132. /**
  133. * session的回收机制
  134. * @param string $lifetime
  135. */
  136. public function gc( $lifetime ){
  137. $this->dbc->GcSession( $lifetime );
  138. }
  139. }
  140. ?>

 

  1. <?php
  2. /**
  3. * session入库的数据库操作类
  4. * @author 删代码工程师  geek-cy.com
  5. *
  6. */
  7. class DbSession{
  8. public static $db = null;
  9. private $con = null; //保存数据库链接资源句柄
  10. private $HOSTNAME = 'localhost';
  11. private $DB = 'phptest';
  12. private $USER = 'root';
  13. private $PASSWORD = '';
  14. const CHARSET = 'UTF8'; //编码设置
  15. static $DEBUG = true; //是否开启错误提示
  16. //session表与表字段
  17. private $TableName = 'session';
  18. protected $phpsession = 'phpsession';
  19. protected $uptime = 'uptime';
  20. protected $data = 'data';
  21. private function __construct(){
  22. $this->contect();
  23. }
  24. private function __clone(){
  25. }
  26. /**
  27. * 初始化链接数据库
  28. * @return Ambigous <NULL, string>
  29. */
  30. public static function InitDbSession(){
  31. if( is_null(self::$db) || !(self::$db instanceof self) ){
  32. self::$db = new DbSession;
  33. }
  34. return self::$db; //返回类对象
  35. }
  36. /**
  37. * 链接数据库
  38. *
  39. */
  40. private  function contect(){
  41. $this->con = mysql_connect($this->HOSTNAME, $this->USER, $this->PASSWORD); //保存数据库连接资源句柄
  42. try{
  43. if( is_null($this->con) ){
  44. throw new Exception('链接数据库失败');
  45. }
  46. if(!mysql_select_db($this->DB, $this->con)){
  47. throw new Exception('选择数据库失败');
  48. }
  49. mysql_query("SET NAMES self::CHARSET");
  50. }catch (Exception $e){
  51. $this->ShowErrow( $e->getMessage() );
  52. }
  53. }
  54. /**
  55. * 输出错误
  56. * @param string $msg
  57. */
  58. protected function ShowErrow( $msg ){
  59. if(static::$DEBUG){ //判断是否打印错误
  60. echo $msg;
  61. }
  62. }
  63. /**
  64. * 读取数据库中保存的session
  65. * @param string $sessionid
  66. * @param array $selectData
  67. * @return boolean|Ambigous <boolean, multitype:>
  68. */
  69. public function ReadSession( $sessionid, array $selectData ){
  70. $selectData = $this->doSelectData($selectData);
  71. if(!$selectData){
  72. return false;
  73. }
  74. if( $this->CheckSessionId($sessionid) ){
  75. $sql = 'SELECT '.$selectData.' FROM `'.$this->TableName.'` WHERE '.$this->phpsession.' = \''.$sessionid.'\' LIMIT 1';
  76. $result = mysql_query($sql, $this->con);
  77. return $this->fetch($result);
  78. }
  79. }
  80. /**
  81. * 写入新session到数据库中
  82. * @param array $insertData
  83. * @return boolean
  84. */
  85. public function InsertSession( array $insertData ){
  86. if( $insertData = $this->doInsertData($insertData) ){
  87. $sql = 'INSERT INTO '.$this->TableName.'('.$insertData[0].') VALUES('.$insertData[1].')';
  88. mysql_query($sql, $this->con);
  89. return true;
  90. }else{
  91. return false;
  92. }
  93. }
  94. /**
  95. * 更新数据库中保存的session
  96. * @param string $sessionid
  97. * @param array $updateData
  98. * @return boolean
  99. */
  100. public function UpdateSession( $sessionid, array $updateData){
  101. if( !$this->CheckSessionId($sessionid) ){
  102. return false;
  103. }
  104. if( $updateData = $this->doUpadateData($updateData) ){
  105. $sql = 'UPDATE '.$this->TableName.' SET '.$updateData.' WHERE '.$this->phpsession.' = \''.$sessionid.'\'';
  106. mysql_query($sql, $this->con);
  107. return true;
  108. }else{
  109. return false;
  110. }
  111. }
  112. /**
  113. * 删除数据库中的session
  114. * @param string $sessionid
  115. * @return boolean
  116. */
  117. public function DeleteSession( $sessionid ){
  118. if( !$this->CheckSessionId($sessionid) ){
  119. return false;
  120. }
  121. $sql = 'DELETE FROM '.$this->TableName.' WHERE \''.$sessionid.'\' = '.$this->phpsession;
  122. mysql_query($sql,$this->con);
  123. return true;
  124. }
  125. /**
  126. * 回收清除数据库中已经获取无用的session
  127. * @param string $lifetime
  128. * @return boolean
  129. */
  130. public function GcSession( $lifetime ){
  131. if( !ctype_digit($lifetime )){
  132. return false;
  133. }
  134. $checktime = time()-$lifetime;
  135. $sql = 'DELETE FROM '.$this->TableName.' WHERE '.$this->uptime.' < '.$checktime ;
  136. mysql_query($sql,$this->con);
  137. return true;
  138. }
  139. /**
  140. * 关闭数据库连接
  141. */
  142. public function MysqlClose(){
  143. mysql_close( $this->con );
  144. }
  145. public function __destruct(){
  146. self::$db = null;
  147. if($this->con instanceof self){
  148. mysql_close( $this->con );
  149. }
  150. }
  151. /**
  152. * 对session id 做合法性检查
  153. * @param string $sessionid
  154. * @return boolean
  155. */
  156. private function CheckSessionId( $sessionid ){
  157. return ctype_alnum($sessionid);
  158. }
  159. /**
  160. * 返回select取得的结果集
  161. * @param  $result
  162. * @return boolean|multitype:
  163. */
  164. private function fetch(  $result ){
  165. if( $result && mysql_num_rows($result) == 1){
  166. $resultArray = array();
  167. $resultArray = mysql_fetch_array($result, MYSQL_ASSOC);
  168. if( !$resultArray || count($resultArray)== 0 ){
  169. return false;
  170. }else{
  171. return $resultArray;
  172. }
  173. }else{
  174. return false;
  175. }
  176. }
  177. /**
  178. * 处理select要查询的字段
  179. * @param array $data
  180. * @return boolean|string
  181. */
  182. private function doSelectData( array $data ){
  183. $keyString = '';
  184. foreach ($data as $value){
  185. $keyString .= '`'.$value.'`,';
  186. }
  187. $keyString   =  substr($keyString,0,-1);
  188. if($keyString == ''){
  189. return false;
  190. }
  191. return $keyString;
  192. }
  193. /**
  194. * 处理要insert进数据库的字段和对应的值
  195. * @param array $data
  196. * @return boolean|string
  197. */
  198. private function doInsertData( array $data ){
  199. $keyString = '';
  200. $valueString = '';
  201. if(array_key_exists($this->phpsession, $data)){
  202. if( !$this->CheckSessionId($data[$this->phpsession]) ){
  203. return false;
  204. }
  205. }
  206. foreach ($data as $key => $value){
  207. $keyString .= '`'.$key.'`,';
  208. if(ctype_digit($value)){
  209. $valueString .= ''.$value.',';
  210. }else{
  211. $valueString .= '\''.$value.'\',';
  212. }
  213. }
  214. if( $keyString != '' && $valueString != ''){
  215. $keyString   =  substr($keyString,0,-1);
  216. $valueString =  substr($valueString,0,-1);
  217. $dataArray[0] = $keyString; //字段
  218. $dataArray[1] = $valueString;//值
  219. return $dataArray;
  220. }else{
  221. return false;
  222. }
  223. }
  224. /**
  225. * 处理update的字段和对应的值
  226. * @param array $data
  227. * @return boolean|string
  228. */
  229. private function doUpadateData( array $data ){
  230. $upDataString = '';
  231. foreach($data as $key => $value){
  232. if(ctype_digit($value)){
  233. $value = ''.$value.'';
  234. }else{
  235. $value = '\''.$value.'\'';
  236. }
  237. $upDataString .= '`'.$key.'` = '.$value.',';
  238. }
  239. $upDataString = substr($upDataString,0,-1);
  240. if( $upDataString == ''){
  241. return false;
  242. }
  243. return $upDataString;
  244. }
  245. }



下面是使用方法:

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

php实现session入库的更多相关文章

  1. Session 入库

    session入库 session机制中的数据分部分存储,1部分在客户端的cookie中,2部分在服务器端的session文件中. 务器端的session文件中存储的是$_SESSION变量中的数据. ...

  2. php SESSION入库的实现

    session入库,就是重写session制机,在session的周期内,获得到session的数据并记录到数据库 Session默认是存放到服务器上的文件中,不方便管理,如果能把session存放到 ...

  3. session高级(session入库)

    我们知道,session是一种会话技术,用来实现跨脚本共享数据. 在之前的php会话技术中我们介绍过,session是存放在服务器端的文件里的,因此session有可能因为文件数量过多,会在查询ses ...

  4. php中session 入库的实现

    ini_set("session.save_handler","user");//session.gc_probability = 1 分子ini_set(&q ...

  5. PHP 实现Session入库/存入redis

    对于大访问量的站点使用默认的Session 并不合适,我们可以将其存入数据库.或者使用Redis KEY-VALUE数据存储方案 首先新建一个session表 CREATE TABLE `sessio ...

  6. session入库

    #存储session的数据表示列结构,可作为参考#创建数据库(可选)CREATE DATABASE session;#使用创建的数据库(可选)USE session;#创建存储session的数据表( ...

  7. Session自定义存储及分布式存储

    默认情况下,PHP 使用内置的文件会话保存管理器(files)来完成会话的保存.我们无需设置,PHP默认将session以文件的形式保存到服务器. 通过调用函数 session_start() 即可手 ...

  8. PHP的学习--cookie和session

    最近读了一点<PHP核心技术与最佳实践>,看了cookie和session,有所收获,结合之前的认识参考了几篇博客,总结一下-- 1. PHP的COOKIE cookie 是一种在远程浏览 ...

  9. Cookie与Session详解

    来源:<PHP核心技术与最佳实践> 列旭松 陈文 著 Cookie与Session详解读书笔记,从概念.操作.应用.注意事项以及区别等几方面详细阐述两者的基础知识,它们都是针对HTTP协议 ...

随机推荐

  1. SharePoint 2013创建应用程序时IIS端口文件夹下没文件

    最近SharePoint 2007迁移到2013的时候,碰到创建应用程序时IIS端口文件夹下没文件的问题,网上找了大把的原因,终于在这里找到了解决方案: Fix: 1. Open IIS on the ...

  2. Apache Thrift - 可伸缩的跨语言服务开发框架 ---转载

    src:http://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/ http://thrift.apache.org/

  3. Chrome 谷歌如何快速实现跨域

    第一步:在你的E盘或者其他盘新建一个文件夹,命名为:E:\MyChromeDevUserData 第二步:找到你的谷歌浏览器快捷图标,鼠标右键选择属性,出现以下界面: 第三步:在目标选项的最后添加:  ...

  4. 使用Visual Studio 2010打造C语言编译器

    相信学习C语言的同学们一直在为自己的windows7不能用vc 6.0而烦恼着.或许有的电脑能使用上,但绝大多数是不能的,而且会出现软件不能兼容的提醒.其实大家都不需要再使用vc6.0了,因为软件更新 ...

  5. redis使用场景之位操作(大数据处理)

    在学习redis的过程了,看到了redis还能用于大数据处理,具体场景如下: 腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下 ...

  6. Flume - 快速入门

    关于Flume,官方定义如下: Apache Flume is a distributed, reliable, and available system for efficiently collec ...

  7. [C语言] 数据结构-算法效率的度量方法-事前分析估算方法

    事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算,抛开与计算机硬件软件有关的因素,一个程序的运行时间,依赖于算法的,好坏和问题的输入规模,所谓问题输入规模是指输入量的多少 推导过程,比 ...

  8. 数组的strong copy理解

      一.数组的不同情况下的copy,mutablecopy分析 1.不可变数组的copy(没有创建新对象,复制的只是指针)       2.不可变数组的mutable copy(创建新对象)     ...

  9. Java基础教程(22)--异常

    一.什么是异常   异常就是发生在程序的执行期间,破坏程序指令的正常流程的事件.当方法中出现错误时,该方法会创建一个对象并将其交给运行时系统.该对象称为异常对象,它包含有关错误的信息,包括错误的类型和 ...

  10. 深入分析 Java 中的中文编码问题【转】

    转:https://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/ 几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是 ...