3

发现有很多朋友一直误以为Session和$_SESSION,Cookie和$_COOKIE是对等的,特意写了一篇文章讨论一下他们之间的关系,免得在面试中掉坑以及在项目中出错

798790-20151210161812933-528617996

上述代码会产生怎么样的结果?

a.php: //报notice级别错误[echo $_COOKIE[‘a’]

这个页面的值不难,将会报出一个notice( Undefined index: a)错误,因为Cookie的返回值具有慢一拍特性,在页面中设置setcookie后,当客户端第一次访问时,需要把Cookie键值对包含在http响应头返 回给客户端,当你下次访问的时候,客户端会着这份具有Cookie值的请求头请求服务器,服务器进行一系列判断(包括对Cookie值范围,Cookie有效期),也就知道当前的客户端存在这一份Cookie值,调用显示出来,然后再用 到其他业务逻辑.。

b.php: //abc

这个页面的值是abc,其实第一次看到这个答案我也很惊讶,感觉上Cookie值不是在A页面被unset掉了吗?怎么还会有呢?

其实原理是这样的:

我们一直对Cookie/Session,$_COOKIE /$_SESSION混为一谈了,其实呢,这四个(两组)是独立开来的,Cookie/Session是属于http协议里的值,$_COOKIE /$_SESSION是属于php里面的全局变量.我们在setcookie的时候,实际上给http协议中的Cookie赋值,而http中的Cookie 与php中的超全局变量$_COOKIE自动关联上(注意只是关联上,类似传值赋值的关系).所以$_COOKIE才有这个值abc,并不是直接将值赋给$_COOKIE超全局变量上的.所以同样道 理,unset($_COOKIE)销毁的是$_COOKIE这个变量,与http头中的Cookie值无关(压根没有影响到),所以在b.php依旧可以打印出来(再输出时$_COOKIE[‘a’]依旧从http协议的Cookie拷贝值)。

解决办法就是 setcookie(a,”,-1)将这个Cookie设置为过期,那么b.php就不能再获取到了.

————————————分割线————————————–

类似的道理也可以用到Session机制里,

798790-20151210192159824-196210593

在这幅图里,最终还是能够打印出$_SESSION的值,因为Session_destroy将http中的Session和超全局变量$_SESSION的关系分离了,并且销毁当前Session_id对应的Session值,详见手册

798790-20151210192857933-1949494893

Session_destroy 是把Session和$_SESSION之间的关系割开了,如果你想重新恢复Session函数功能,你就要重新打开session_start(),;例如下图,

798790-20151210193345621-1349901595

Session_unset和普通unset是一个道理,但操作的是HTTP协议中的Session值,可看手册

捕获

这样子Session值就会被顺利删掉,那么与它关联的$_SESSION超全局变量值也就消失了

总结:

session_unset销毁的不是$_SESSION这个变量值,而是http中的Session值.具体可以自己分别开启与不开启session_start然后session_unset进行实验
unset这个函数不同,unset直接操作变量,Cookie和$_COOKIE是传值赋值关系
session_destroy的作用是将SESSION与$_SESSION之间的联系切除掉
$_SESSION/Session值,$_COOKIE/Cookie值不是对等的,cookie/Session操作着$_COOKIE/$_SESSION变量值,所以在进行函数操作的时候一定要搞明白,他究竟是对变量操作还是http协议操作!
让Cookie过期最好的策略是将它过期而不是unset.

大菌说事
4.9k 声望683 粉丝