解析php session_set_save_handler 函数的用法(mysql)


Posted in PHP onJune 29, 2013
<?php 
/*============================文件说明======================================== 
@filename:     session.class.php 
@description:  数据库保存在线用户session,实现在线用户功能! 
@notice:       session过期时间一个小时,因为我们的站点是使用cookie(有效时间是1小时)登录。                 


  因此我们只记录用户登录的时间,而不是刷新一次更新一次                 



  删除数据库中session记录的动作发生在用户超时后执行这个文件或正常退出(session_destory)  
@database:     database:sessions  field:sessionid(char32),uid(int10),last_visit(int10) 
=============================================================================
*/
 class session { 
     private $db; 
     private $lasttime=3600;//超时时间:一个小时
      function session(&$db) { 
         $this->db = &$db;
         session_module_name('user'); //session文件保存方式,这个是必须的!除非在Php.ini文件中设置了
         session_set_save_handler( 
             array(&$this, 'open'), //在运行session_start()时执行
              array(&$this, 'close'), //在脚本执行完成或调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完后被执行 
             array(&$this, 'read'), //在运行session_start()时执行,因为在session_start时,会去read当前session数据
             array(&$this, 'write'), //此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行
              array(&$this, 'destroy'), //在运行session_destroy()时执行
              array(&$this, 'gc') //执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,session_start会相继执行open,read和gc
         ); 
         session_start(); //这也是必须的,打开session,必须在session_set_save_handler后面执行
     } 
        function unserializes($data_value) { 
         $vars = preg_split( 
             '/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\|/', 
             $data_value, -1, PREG_SPLIT_NO_EMPTY | 
             PREG_SPLIT_DELIM_CAPTURE 
         ); 
         for ($i = 0; isset($vars[$i]); $i++) { 
             $result[$vars[$i++]] = unserialize($vars[$i]); 
         } 
         return $result; 
     }  
     function open($path, $name) { 
         return true; 
     } 
     function close() { 
         $this->gc($this->lasttime);
         return true; 
     } 
    function read($SessionKey){
         $sql = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1"; 
         $query =$this->db->query($sql);
         if($row=$this->db->fetch_array($query)){
           return $row['uid'];
         }else{
             return ""; 
         }
              } 
     function write($SessionKey,$VArray) { 
         require_once(MRoot.DIR_WS_CLASSES .'db_mysql_class.php');
        $db1=new DbCom();
       // make a connection to the database... now
        $db1->connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
        $db1->query("set names utf8");
        $this->db=$db1;
        $SessionArray = addslashes($VArray);
         $data=$this->unserializes($VArray);   
                          $sql0 = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1"; 
         $query0 =$this->db->query($sql0);
         if($this->db->num_rows($query0)<=0){
             if (isset($data['webid']) && !empty($data['webid'])) { 
                $this->db->query("insert into `sessions` set `session_id` = '$SessionKey',uid='".$data['webid']."',last_visit='".time()."'");
             }    
                    return true;
         }else{
             /*$sql = "update `sessions` set "; 
             if(isset($data['webid'])){
             $sql .= "uid = '".$data['webid']."', " ;
             }
             $sql.="`last_visit` = null " 
                   . "where `session_id` = '$SessionKey'"; 
                               $this->db->query($sql); */
             return true; 
         }    
     } 
   function destroy($SessionKey) { 
      $this->db->query("delete from `sessions` where `session_id` = '$SessionKey'"); 
      return true; 
    } 
    function gc($lifetime) {
        $this->db->query("delete from `sessions` where unix_timestamp(now()) -`last_visit` > '".$this->lasttime."'");
        return true;
    } 
     } 
 ?>

下面是php.ini中session的配置说明:
session.save_handler = "files"
 存储和检索与会话关联的数据的处理器名字。默认为文件("files")。
 如果想要使用自定义的处理器(如基于数据库的处理器),可用"user"。
 有一个使用PostgreSQL的处理器:http://sourceforge.net/projects/phpform-ext/

session.save_path = "/tmp"
 传递给存储处理器的参数。对于files处理器,此值是创建会话数据文件的路径。
 Windows下默认为临时文件夹路径。
 你可以使用"N[MODE]/path"这样模式定义该路径(N是一个整数)。
 N表示使用N层深度的子目录,而不是将所有数据文件都保存在一个目录下。
 [MODE]可选,必须使用8进制数,默认600(=384),表示每个目录下最多保存的会话文件数量。
 这是一个提高大量会话性能的好主意。
 注意0: "N[MODE]/path"两边的双引号不能省略。
 注意1: [MODE]并不会改写进程的umask。
 注意2: php不会自动创建这些文件夹结构。请使用ext/session目录下的mod_files.sh脚本创建。
 注意3: 如果该文件夹可以被不安全的用户访问(比如默认的"/tmp"),那么将会带来安全漏洞。
 注意4: 当N>0时自动垃圾回收将会失效,具体参见下面有关垃圾搜集的部分。

session.name = "PHPSESSID"
用在cookie里的会话ID标识名,只能包含字母和数字。

session.auto_start = Off
 在客户访问任何页面时都自动初始化会话,默认禁止。
 因为类定义必须在会话启动之前被载入,所以若打开这个选项,你就不能在会话中存放对象。

session.serialize_handler = "php"
 用来序列化/解序列化数据的处理器,php是标准序列化/解序列化处理器。
 另外还可以使用"php_binary"。当启用了WDDX支持以后,将只能使用"wddx"。

session.gc_probability = 1
session.gc_divisor = 100
 定义在每次初始化会话时,启动垃圾回收程序的概率。
 这个收集概率计算公式如下:session.gc_probability/session.gc_divisor
 对会话页面访问越频繁,概率就应当越小。建议值为1/1000~5000。

session.gc_maxlifetime = 1440
 超过此参数所指的秒数后,保存的数据将被视为'垃圾'并由垃圾回收程序清理。
 判断标准是最后访问数据的时间(对于FAT文件系统是最后刷新数据的时间)。
 如果多个脚本共享同一个session.save_path目录但session.gc_maxlifetime不同,
 那么将以所有session.gc_maxlifetime指令中的最小值为准。
 如果使用多层子目录来存储数据文件,垃圾回收程序不会自动启动。
 你必须使用一个你自己编写的shell脚本、cron项或者其他办法来执行垃圾搜集。
 比如,下面的脚本相当于设置了"session.gc_maxlifetime=1440" (24分钟):
 cd /path/to/sessions find -cmin +24 | xargs rm

session.referer_check =
 如果请求头中的"Referer"字段不包含此处指定的字符串则会话ID将被视为无效。
 注意:如果请求头中根本不存在"Referer"字段的话,会话ID将仍将被视为有效。
 默认为空,即不做检查(全部视为有效)。

session.entropy_file = "/dev/urandom"
 附加的用于创建会话ID的外部高熵值资源(文件),
 例如UNIX系统上的"/dev/random"或"/dev/urandom"

session.entropy_length = 0
 从高熵值资源中读取的字节数(建议值:16)。

session.use_cookies = On
 是否使用cookie在客户端保存会话ID

session.use_only_cookies = Off
 是否仅仅使用cookie在客户端保存会话ID
 打开这个选项可以避免使用URL传递会话带来的安全问题。
 但是禁用Cookie的客户端将使会话无法工作。

session.cookie_lifetime = 0
 传递会话ID的Cookie有效期(秒),0 表示仅在浏览器打开期间有效。

session.cookie_path = "/"
 传递会话ID的Cookie作用路径。

session.cookie_domain =
 传递会话ID的Cookie作用域。
 默认为空表示表示根据cookie规范生成的主机名。

session.cookie_secure = Off
 是否仅仅通过安全连接(https)发送cookie。

session.cookie_httponly = Off
 是否在cookie中添加httpOnly标志(仅允许HTTP协议访问),
 这将导致客户端脚本(JavaScript等)无法访问该cookie。
 打开该指令可以有效预防通过XSS攻击劫持会话ID。

session.cache_limiter = "nocache"
 设为{nocache|private|public}以指定会话页面的缓存控制模式,
 或者设为空以阻止在http应答头中发送禁用缓存的命令。

session.cache_expire = 180
 指定会话页面在客户端cache中的有效期限(分钟)
 session.cache_limiter=nocache时,此处设置无效。

session.use_trans_sid = Off
 是否使用明码在URL中显示SID(会话ID)。
 默认是禁止的,因为它会给你的用户带来安全危险:
 1- 用户可能将包含有效sid的URL通过email/irc/QQ/MSN…途径告诉给其他人。
 2- 包含有效sid的URL可能会被保存在公用电脑上。
 3- 用户可能保存带有固定不变sid的URL在他们的收藏夹或者浏览历史纪录里面。
 基于URL的会话管理总是比基于Cookie的会话管理有更多的风险,所以应当禁用。

session.bug_compat_42 = On
session.bug_compat_warn = On
 PHP4.2之前的版本有一个未注明的"BUG":
 即使在register_globals=Off的情况下也允许初始化全局session变量,
 如果你在PHP4.3之后的版本中使用这个特性,会显示一条警告。
 建议关闭该"BUG"并显示警告。

session.hash_function = 0
 生成SID的散列算法。SHA-1的安全性更高一些
 0: MD5 (128 bits)
 1: SHA-1 (160 bits)
 建议使用SHA-1。

session.hash_bits_per_character = 4
 指定在SID字符串中的每个字符内保存多少bit,
 这些二进制数是hash函数的运算结果。
 4: 0-9, a-f
 5: 0-9, a-v
 6: 0-9, a-z, A-Z, "-", ","
 建议值为 5

url_rewriter.tags = "a=href,area=href,frame=src,form=,fieldset="
 此指令属于PHP核心部分,并不属于Session模块。
 指定重写哪些HTML标签来包含SID(仅当session.use_trans_sid=On时有效)
 form和fieldset比较特殊:
 如果你包含他们,URL重写器将添加一个隐藏的"<input>",它包含了本应当额外追加到URL上的信息。
 如果要符合XHTML标准,请去掉form项并在表单字段前后加上<fieldset>标记。
 注意:所有合法的项都需要一个等号(即使后面没有值)。
 推荐值为"a=href,area=href,frame=src,input=src,form=fakeentry"。

PHP 相关文章推荐
PHP 日志缩略名的创建函数代码
May 26 PHP
仿AS3实现PHP 事件机制实现代码
Jan 27 PHP
探讨:如何使用PhpDocumentor生成文档
Jun 25 PHP
PHP中对缓冲区的控制实现代码
Sep 29 PHP
destoon调用自定义模板及样式的公告栏
Jun 21 PHP
PHP实现根据设备类型自动跳转相应页面的方法
Jul 24 PHP
PHP针对常规模板引擎中与CSS/JSON冲突的解决方法
Aug 19 PHP
php实现网页端验证码功能
Jul 11 PHP
yii2多图上传组件的使用教程
May 10 PHP
在Laravel中使用DataTables插件的方法
May 29 PHP
php实现微信公众号创建自定义菜单功能的实例代码
Jun 11 PHP
PHP code 验证码生成类定义和简单使用示例
May 27 PHP
使用PHP获取当前url路径的函数以及服务器变量
Jun 29 #PHP
如何使用PHP实现javascript的escape和unescape函数
Jun 29 #PHP
解析php中的escape函数
Jun 29 #PHP
使用PHP会话(Session)实现用户登陆功能
Jun 29 #PHP
php获取数组中重复数据的两种方法
Jun 28 #PHP
php setcookie(name, value, expires, path, domain, secure) 参数详解
Jun 28 #PHP
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法
Jun 28 #PHP
You might like
一个好用的分页函数
2006/11/16 PHP
php实例分享之通过递归实现删除目录下的所有文件详解
2014/05/15 PHP
php实现的CSS更新类实例
2014/09/22 PHP
Yii 框架入口脚本示例分析
2020/05/19 PHP
javascript显示隐藏层比较不错的方法分析
2008/09/30 Javascript
基于JQuery的数字改变的动画效果--可用来做计数器
2010/08/11 Javascript
非常强大的 jQuery.AsyncBox 弹出对话框插件
2011/08/29 Javascript
获得所有表单值的JQuery实现代码[IE暂不支持]
2012/05/24 Javascript
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
2013/04/17 Javascript
node.js中使用node-schedule实现定时任务实例
2014/06/03 Javascript
AngularJS学习笔记之TodoMVC的分析
2015/02/22 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
javascript匀速动画和缓冲动画详解
2016/10/20 Javascript
详解webpack+angular2开发环境搭建
2017/06/28 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
vue组件name的作用小结
2018/05/23 Javascript
Vue.js样式动态绑定实现小结
2019/01/24 Javascript
详解js根据百度地图提供经纬度计算两点距离
2019/05/13 Javascript
Vue实现todo应用的示例
2021/02/20 Vue.js
[04:28]DOTA2亚洲邀请赛小组赛第五日 TOP10精彩集锦
2015/02/03 DOTA
[01:06]DOTA2小知识课堂 Ep.01 TP出门不要忘记帮队友灌瓶哦
2019/12/05 DOTA
实例讲解Python中的私有属性
2014/08/21 Python
python命令行参数解析OptionParser类用法实例
2014/10/09 Python
Python的Flask框架中web表单的教程
2015/04/20 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
2019/07/19 Python
Python3 解决读取中文文件txt编码的问题
2019/12/20 Python
Python编程快速上手——选择性拷贝操作案例分析
2020/02/28 Python
Django调用支付宝接口代码实例详解
2020/04/04 Python
Sperry澳大利亚官网:源自美国帆船鞋创始品牌
2019/07/29 全球购物
印度在线购买电子产品网站:Croma
2020/01/02 全球购物
2014法制宣传日活动总结范文
2014/11/01 职场文书
法人代表资格证明书
2015/06/18 职场文书
如何在CSS中绘制曲线图形及展示动画
2021/05/24 HTML / CSS
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP
Python 内置函数速查表一览
2021/06/02 Python
java泛型通配符详解
2021/07/25 Java/Android