本篇文章是对php中session_set_save_handler 函数的用法(mysql)进行了详细的分析介绍
需要的朋友参考下
复制代码 代码如下:
<?php
/*============================文件说明========================================
@filename: session
class
php
@description: 数据库保存在线用户session
实现在线用户功能!
@notice: session过期时间一个小时
因为我们的站点是使用cookie(有效时间是
小时)登录
因此我们只记录用户登录的时间
而不是刷新一次更新一次
删除数据库中session记录的动作发生在用户超时后执行这个文件或正常退出(session_destory)
@database: database:sessions field:sessionid(char
)
uid(int
)
last_visit(int
)
=============================================================================
*/
class session {
private $db;
private $lasttime=
;//超时时间
一个小时
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_x
f
xff][a
zA
Z
_x
f
xff]*)|/
$data_value
PREG_SPLIT_NO_EMPTY |
PREG_SPLIT_DELIM_CAPTURE
);
for ($i =
; 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
";
$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
);
$db
=new DbCom();
// make a connection to the database
now
$db
>connect(DB_SERVER
DB_SERVER_USERNAME
DB_SERVER_PASSWORD
DB_DATABASE);
$db
>query("set names utf
");
$this
>db=$db
;
$SessionArray = addslashes($VArray);
$data=$this
>unserializes($VArray);
$sql
= "SELECT uid FROM sessions WHERE session_id =
"
$SessionKey
"
limit
";
$query
=$this
>db
>query($sql
);
if($this
>db
>num_rows($query
)<=
){
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;
}
}
?>
下面是phpini中session的配置说明
sessionsave_handler = "files"
存储和检索与会话关联的数据的处理器名字默认为文件("files")
如果想要使用自定义的处理器(如基于数据库的处理器)可用"user"
有一个使用PostgreSQL的处理器
sessionsave_path = "/tmp"
传递给存储处理器的参数对于files处理器此值是创建会话数据文件的路径
Windows下默认为临时文件夹路径
你可以使用"N[MODE]/path"这样模式定义该路径(N是一个整数)
N表示使用N层深度的子目录而不是将所有数据文件都保存在一个目录下
[MODE]可选必须使用进制数默认(=)表示每个目录下最多保存的会话文件数量
这是一个提高大量会话性能的好主意
注意: "N[MODE]/path"两边的双引号不能省略
注意: [MODE]并不会改写进程的umask
注意: php不会自动创建这些文件夹结构请使用ext/session目录下的mod_filessh脚本创建
注意: 如果该文件夹可以被不安全的用户访问(比如默认的"/tmp")那么将会带来安全漏洞
注意: 当N>时自动垃圾回收将会失效具体参见下面有关垃圾搜集的部分
sessionname = "PHPSESSID"
用在cookie里的会话ID标识名只能包含字母和数字
sessionauto_start = Off
在客户访问任何页面时都自动初始化会话默认禁止
因为类定义必须在会话启动之前被载入所以若打开这个选项你就不能在会话中存放对象
sessionserialize_handler = "php"
用来序列化/解序列化数据的处理器php是标准序列化/解序列化处理器
另外还可以使用"php_binary"当启用了WDDX支持以后将只能使用"wddx"
sessiongc_probability =
sessiongc_divisor =
定义在每次初始化会话时启动垃圾回收程序的概率
这个收集概率计算公式如下sessiongc_probability/sessiongc_divisor
对会话页面访问越频繁概率就应当越小建议值为/~
sessiongc_maxlifetime =
超过此参数所指的秒数后保存的数据将被视为垃圾并由垃圾回收程序清理
判断标准是最后访问数据的时间(对于FAT文件系统是最后刷新数据的时间)
如果多个脚本共享同一个sessionsave_path目录但sessiongc_maxlifetime不同
那么将以所有sessiongc_maxlifetime指令中的最小值为准
如果使用多层子目录来存储数据文件垃圾回收程序不会自动启动
你必须使用一个你自己编写的shell脚本cron项或者其他办法来执行垃圾搜集
比如下面的脚本相当于设置了"sessiongc_maxlifetime=" (分钟)
cd /path/to/sessions find cmin + | xargs rm
sessionreferer_check =
如果请求头中的"Referer"字段不包含此处指定的字符串则会话ID将被视为无效
注意如果请求头中根本不存在"Referer"字段的话会话ID将仍将被视为有效
默认为空即不做检查(全部视为有效)
sessionentropy_file = "/dev/urandom"
附加的用于创建会话ID的外部高熵值资源(文件)
例如UNIX系统上的"/dev/random"或"/dev/urandom"
sessionentropy_length =
从高熵值资源中读取的字节数(建议值)
sessionuse_cookies = On
是否使用cookie在客户端保存会话ID
sessionuse_only_cookies = Off
是否仅仅使用cookie在客户端保存会话ID
打开这个选项可以避免使用URL传递会话带来的安全问题
但是禁用Cookie的客户端将使会话无法工作
sessioncookie_lifetime =
传递会话ID的Cookie有效期(秒) 表示仅在浏览器打开期间有效
sessioncookie_path = "/"
传递会话ID的Cookie作用路径
sessioncookie_domain =
传递会话ID的Cookie作用域
默认为空表示表示根据cookie规范生成的主机名
sessioncookie_secure = Off
是否仅仅通过安全连接(https)发送cookie
sessioncookie_httponly = Off
是否在cookie中添加httpOnly标志(仅允许HTTP协议访问)
这将导致客户端脚本(JavaScript等)无法访问该cookie
打开该指令可以有效预防通过XSS攻击劫持会话ID
sessioncache_limiter = "nocache"
设为{nocache|private|public}以指定会话页面的缓存控制模式
或者设为空以阻止在http应答头中发送禁用缓存的命令
sessioncache_expire =
指定会话页面在客户端cache中的有效期限(分钟)
sessioncache_limiter=nocache时此处设置无效
sessionuse_trans_sid = Off
是否使用明码在URL中显示SID(会话ID)
默认是禁止的因为它会给你的用户带来安全危险
用户可能将包含有效sid的URL通过email/irc/QQ/MSN…途径告诉给其他人
包含有效sid的URL可能会被保存在公用电脑上
用户可能保存带有固定不变sid的URL在他们的收藏夹或者浏览历史纪录里面
基于URL的会话管理总是比基于Cookie的会话管理有更多的风险所以应当禁用
sessionbug_compat_ = On
sessionbug_compat_warn = On
PHP之前的版本有一个未注明的"BUG"
即使在register_globals=Off的情况下也允许初始化全局session变量
如果你在PHP之后的版本中使用这个特性会显示一条警告
建议关闭该"BUG"并显示警告
sessionhash_function =
生成SID的散列算法SHA的安全性更高一些
: MD ( bits)
: SHA ( bits)
建议使用SHA
sessionhash_bits_per_character =
指定在SID字符串中的每个字符内保存多少bit
这些二进制数是hash函数的运算结果
: af
: av
: az AZ "" ""
建议值为
url_rewritertags = "a=hrefarea=hrefframe=srcform=fieldset="
此指令属于PHP核心部分并不属于Session模块
指定重写哪些HTML标签来包含SID(仅当sessionuse_trans_sid=On时有效)
form和fieldset比较特殊
如果你包含他们URL重写器将添加一个隐藏的"<input>"它包含了本应当额外追加到URL上的信息
如果要符合XHTML标准请去掉form项并在表单字段前后加上<fieldset>标记
注意所有合法的项都需要一个等号(即使后面没有值)
推荐值为"a=hrefarea=hrefframe=srcinput=srcform=fakeentry"