会话控制技术
一、为什么使用会话控制?
web是通过http协议来实现的,而http协议又是无状态的协议,http没有一个内建机制来维护两个事物之间的状态。所有同一个用户请求同一个页面两次的时候,http会把这两次请求隔离开,会当成两次请求的独立。
如果用户执行了登录操作,再次请求页面时http不会认为该用户已经登录过,因此不会保存用户的登录状态,所以不能再不同的页面之间做用户的跟踪和状态的保存。
会话控制就是解决这样的问题的。
思想就是:允许服务器跟踪同一个客户端做出的连续请求,这样就可以保存用户的状态,完成用户的登录状态的保存。
二、会话控制的实现方式
① 通过GET参数进行传递;[不建议使用]
例:用户在1页面完成登录操作,当跳转到2页面时,我们将用户的登录信息继续往下传递,然后在2页面处理的时候就可以判断用户是否执行了登录操作。
存在的问题:
1,信息不安全,所有的信息都会暴露在URL地址中;
2,在传递过程中参数可能会丢失。
cookie的操作:
写操作: setcookie($name, $value, $expire, $path, $domain, $scure );
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
setcookie() 定义了 Cookie,会和剩下的 HTTP 头一起发送给客户端。 和其他 HTTP 头一样,必须在脚本产生任意输出之前发送 Cookie(由于协议的限制)。 请在产生任何输出之前(包括 <html> 和 <head> 或者空格)调用本函数。
一旦设置 Cookie 后,下次打开页面时可以使用 $_COOKIE 读取。 Cookie 值同样也存在于 $_REQUEST。
$name : cookie 名称;
$value : cookie 的值。(这个值存储在用户电脑中的,请勿保存敏感和重要信息);
$expire : cookie 的过期时间,时间戳格式。如果设置成0或者忽略此参数,cookie会在会话结束时过期(关系浏览器);
$path : cookie有效的服务器路径,默认值是设置cookie的当前路径;
$domain : cookie的有效域名/子域名;
$secure : 设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。 设置成 TRUE 时,只有安全连接存在时才会设置 Cookie。 如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie (通过 $_SERVER["HTTPS"] 判断)。
保存cookie为数组形式:setcookie( 'a[b]', $value ); 保存为二维数组
读取cookie : $_COOKIE 就可以了;
删除cookie : setcookie($name, " ", time() - 1000); //设置cookie过期可以了(触发浏览器的删除机制)。
cookie的优缺点:
优点:cookie是存储在客户端中硬盘或者内存中的,不会消耗服务器资源。
缺点:由于所有信息保存在客户端用户的计算机,不建议将一些敏感和重要的信息保存到cookie,而且用户可以禁用cookie,一旦用户禁用cookie就不能获取用户信息了。
③ session 【特别注意:session不是完全脱离cookie的,而是基于cookie的】
工作原理:将使用者相同的信息存储在服务器中的,这样用户无法禁用session的使用,相较于cookie来说安全。session不是脱离cookie的,而是基于cookie的,sessionid是保存在cookie中的,
如果用户禁用了cookie,可以使用URL的方式进行传递sessionID,从而保存session的状态;
session的信息默认是存储在服务器中的文件中,每当用户读取session的内容的时候,首先会拿到浏览器中携带sessionid的cookie,根据sessionID找到对应的session文件,将里面的信息读取出来。
session的操作:
开启session; session_start(); 然后操作这个超全局数组
查看 $_SESSION
销毁session[清空session] ;$_SESSION = []; 或者 $_SESSION = NULL;
删除session文件:session_destroy() 删除session文件并且将sessionID对应的cookie文件也销毁掉;
php.ini 中关于session的配置:
session.auto_start
; 是否自动开启session_start;
session.cookie_domain
; 指定了要设定会话cookie的域名;
session.cookie_lifetime
; 值为0时,告知浏览器不要持久化存储cookie数据
session.cookie_path
; 指定了要设置回话cookie的路径 , 默认是/
session.name
; 指定回话名,用作cookie的名字,只能有数字和字母组成,默认是 PHPSESSID
session.save_path
; session 文件保存在服务器的路径
session.use_cookie
; 是否在客户端使用cookie传递 sessionID
session.use_trans_sid
; 是否使用传递的方式传递sessionId;
session.save_handler
; 定义了来存储和获取与会话关联的数据的处理器的名字。例如:redis
, membean
session.gc_probablity
; 与 session.gc_divisor
组合来管理垃圾回收,进程使用概率,默认是1
session.gc_divisor
;
session.gc_divisor
与 session.gc_probability
合起来定义了在每个会话初始化时启动 gc(garbage collection 垃圾回收)进程的概率。此概率用 gc_probability/gc_divisor
计算得来。例如 1/100 意味着在每个请求中有 1% 的概率启动 gc 进程。session.gc_divisor
默认为 100
。
session.maxlifetime
; 指定过了多少秒之后数据就会被视为“垃圾”并被清除。垃圾搜集可能会在 session 启动的时候开始 ([默认1440 秒 当前时间戳减去session文件最后修改的时间 超过1440秒的就看做是过期
] )
session
的优缺点:
优点:session的信息,是存储在服务器的,相对很安全。客户端不可能获取到session数据;
缺点:占用服务器资源,时间长的话,session文件会变大,效率会降低。
【分布式问题:可以将session信息保存到内存服务器中,比如Redis。。。每台web服务器请求时都会去Redis中获取session信息】
传递 sessionID
的问题:
session是基于cookie的,而不是脱离cookie的。sessionID信息保存在cookie中的,如果用户禁用了cookie可以使用session_name()和session_id()来传递sessionID;
方法①:直接使用session_name()和session_id()
<a href="1.php?"<?php echo session_name()."=".session_id() ?></a>
方法②:使用SID常量【推荐使用】
<a href="1.php?"<?php echo SID ?></a>
使用SID常量:当开启cookie的时候,SID的值为空;如果没有开启cookie或者用户禁用了cookie的话,SID才是session_name()和session_id()的拼接。所有SID常量比较智能,建议使用。
session存储问题:
假如使用多台web服务器,其中一台存储了sessionid的信息。当轮询的时候可能被分配到另一台web服务器,此时这台服务器中不会找到sessionid 对应的信息。。。
解决方法:
可以将session信息保存到Redis等内存服务器中,每次轮询时都去Redis中拿sessionID对应的session信息就解决此问题了。
session_set_save_handler():可以自定义session会话存储函数;
充分理解cookie和session的工作原理,和两者的区别!!!