本文内容说明:
1.说明会话技术存在原因: HTTP协议的误状态
2.会话技术实现方式:
2.1 get实现: 信息不安全,参数易丢失
2.2 Cookie存客户浏览器,虽然不占服务器资源,但是重要信息不建议存浏览器,而且客户可以禁用浏览器cookie
2.3 session存服务器,基于cookie实现,讲了php.ini的session配置
1.为什么要使用会话控制技术?
web是通过http协议来实现的, 而http协议是无状态的协议
http没有一个内建机制来维护两个事物之间的状态。所以同一个用户在请求相同的页面两次的时候,http不会认为两次请求都来自于同一个用户,会把它当成是两次请求的独立
所以如果一个用户做个登录,http协议不会理解为已经做过登录,因为他没有办法保持用户之前的登录状态,所以没有办法保持用户在不用页面的跟踪和状态的保持,而对于我们的会话控制技术来说就是为了解决这样的问题
2.会话控制技术的实现方式
2.1 通过GET参数来传递
信息不安全暴露在地址栏 信息参数易丢失 不建议使用
2.2 Cookie
cookie是存储在浏览器里的一个文件,文件里面包含客户端片段的信息
cookie的操作包括:
//写操作
setcookie($name, $value, $expire, $path, $domain, $secure);
//$name 键名 $value 值 $expire 过期时间 $path 路径 $domain 域名 $secure 是否安全
//读操作
$_COOKIE
//可以数组形式存储
setcookie('a[b]', 'val');
//删除cookie的处理
setcookie($name, '', time()-1000); //让cookie过期
cookie 的优点,存在客户端的不会占用服务器资源,缺点,也是存储在客户端所以一些重要信息不建议用 cookie
而且用户可以有权禁用cookie
2.3 Session 存储在服务器中 session是基于cookie的
用cookie来存储sessionid 如果cookie被禁用,可以通过url来传 session存储在服务中的一个session文件
session的操作:
session_start();
$_SESSION;
$_SESSION = []; //销毁一个session
session_destroy(); //会删除session文件 及文件对应的 cookie也删除
session的配置: php.ini中的配置
session.save_path="/data/tmp/session";
//用文件做介质,session存储路径;用memcache做介质时用作服务器连接串:
session.save_path =“tcp://127.0.0.1:11211”
//有一种设置是"N;/path",这是随机分级存储,这个样的话,垃圾回收将不起作用,需要自己写脚本session.save_handler = “files”;
//可选files,memcache,user。如果想要自定义处理器来存取session数据,比如database, redis就用"user"
session.name = “PHP_SESSION”
//当做cookie name来使用的session标识名
session.cookie_domain = “a.com” //cookie有效作用域名
session.use_cookies = 1 //是否使用cookies在客户端保存会话sessionid 默认为采用cookies
session.auto_start = 0
//是否自动启用session,默认不启用。在使用session功能时,在每个php脚本头部都会通过session_start()函数来启动session
session.cookie_lifetime = 0
//传递sessionid的cookie有效期(秒), 0表示仅在浏览器打开期间有效
session.gc_probability = 1
session.gc_divisor = 1000
//概率是 session.gc_probabilty/session.gc_divisor结果1/1000,
//不建议设置过小,因为session的垃圾回收,是需要检查每个文件是否过期的 session.gc_maxlifetime = 1440 //过期时间默认24分钟
//设定保存的session文件生存期,超过此参数设定秒数后,保存的数据将被视为’垃圾’并由垃圾回收程序清理。判断标准是最后访问数据的时间(对于FAT文件系统是最后刷新数据的时间)。如果多个脚本共享同一个session.save_path目录但session.gc_maxlifetime不同,将以所有session.gc_maxlifetime指令中的最小值为准。
//如果在session.save_path选项中设定使用子目录来存储session数据文件,垃圾回收程序不会自动启动,必须使用自己编写的shell脚本、cron项或者其他办法来执行垃圾搜集。如:cd /path/to/sessions; find -cmin +24 | xargs rm
session.use_trans_sid session值跨脚本(跨页面)传递
基础说明: session会话中传递SESSIONID有两种方式, 1基于cookie传递(常用方式) 2基于URL传递
如果用户的客户端(浏览器)禁止了cookie,那么基于cookie的传递就不能成功,跨页面就无法传递session值了,这个时候可以通过php.ini中设置session.use_trans_sid=1
达到跨页面传递的效果,具体情况看下面的实例
@假设客户端已经禁用了cookie传值,并且php.ini中设置session.use_trans_sid=1(或者php代码中设置set_ini(session.use_trans_sid=1)
页面a.php代码
<?php
session_start();
$_SESSION['name'] = "LIUWEMBIN";
$url = "<a href='b.php'>下一页</a>"; echo $url;
页面b.php代码
<?php
session_start();
echo $_SESSION['name'];
@假设客户端已经禁止了cookie传值,并且php.ini中设置session.use_trans_sid=0(或者php代码中设置set_ini(session.use_trans_sid=0))
页面a.php代码
<?php
session_start();
$_SESSION['name'] = "LIUWEMBIN";
$sessionid = session_id();
$url = "<a href='b.php?session=$sessid'>下 一页</a>";
echo $url;
页面b.php代码
<?php
session_id($_GET['sessid']);
session_start();
echo $_SESSION['name'];
上面两种情况总结:
1. a.php页面中必须要有<a href='b.php'>下一页</a>和<a href='b.php?sessid=$sessid'>下一页</a>这样的超链接,通过超链传递SESSIONID给b.php,如果是直接访问在浏览器中访问的b.php就只有cookie传值才能成功,所以此方法就必须通过URL传递
2.如果设置session.use_trans_sid=1,即使在a.php页面中的<a href='b.php'>这个链接中不添加"?sessid=$sessid" php会自动添加的,而且在b.php中不需要session_id($_GET['sessid']); php也会自动获取到SESSIONID,但是如果session.use_trans_sid=0那么"?sessid=$sessid"和session_id($_GET['sessid']);是必须出现在应该出现的位置,不然无法跨页面获取sessin取得
补充:
session.use_trans_sid=1,表示当客户端浏览器禁止cookie的时候,页面上的链接会基于url传递SESSIONID。但是很多人仅仅设置了这个选项并没有达到效果,后来发现php.ini中还有两个选项
session.use_cookies=1
session.use_only_cookies=1
session.use_cookies表示是否开始基于cookies的session会话
session.use_only_cookies 表示是否开启基于cookies 的session的会话方式
就是说如果session.use_trans_sid=1并且客户端浏览器禁止cookie的时候,达不到效果,就要注意session.use_only_cookies的值是否为0
- session的垃圾回收机制
session.gc_probability = 1
session.gc_divisor = 1000
//概率是 session.gc_probabilty/session.gc_divisor结果1/1000,
//不建议设置过小,因为session的垃圾回收,是需要检查每个文件是否过期的session.gc_maxlifetime = 1440 //过期时间默认24分钟 表示每1000次调用session_start会有1次去清除文件 当前时间戳-文件最后修改时间戳>1440秒 则文件过期了,进行清理 gc_divisor不建议配置的太小,太消耗服务器资源,降低效率 session的优点: 信息比较安全 缺点占用服务资源
4.4.sessionid的问题
正常< a href=“1.php”>下个页面 我们通过cookie在1.php中拿到sessionid
4.1 cookie被禁用 没发传递sessionid
可以通过session_name() 和session_id() 这两个函数进行传递
//sessid的值就是session文件名称 默认是sess_sessionid的值
<a href="1.php?PHPSESSID=sessid的值">下个页面</a>
//sessid的值比较长
<a href="1.php?<?php echo session_name().'='.session_id() ?>">下个页面</a>
//上面写法还是很长
<a href="1.php?<?php echo SID;?>">下个页面</a>
SID是php的一个常量 session_name().'='.session_id()
SID特性:如果开启了cookie SID为空 如果没有开启cookie 则SID才是上面字符串的拼接
所以sid还是比较智能的也建议使用
5.session的存储
多台web服务器session存储在其中一台中, 如果存储在文件则不合适会找不到
因此建议存储到内存中 使用session_set_save_handler(); 可以存到MYSQL Memcache redis中
session信息的存储方式,如何进行遍历
可以文件也可以数据库等 通过session_set_save_handler 遍历直接$_SESSION就可以了