PHP 中 Session 和 Cookie 应用
PHP设置session的生命周期
PHP中,Session变量保存在服务器端(默认以文件格式保存),而Session ID以cookie形式保存在客户端。
销毁session的方法有2种方法
第一种 通过程序
session_destory() // 清除所有session
unset(session['x']) // 清除指定的session['x']
第二种 关闭浏览器
关闭浏览器后,会直接清除所有session
在Cookie没有禁用的情况下,session ID是保存在Cookie中的
想要改变session生命周期,可以通过设置Cookie中session ID的有效时间来实现
说明:PHP 默认的 Session ID 为 PHPSESSID,在 php.ini 中可以自定义为 MIMVPSESSID
例如:访问米扑代理首页 https://proxy.mimvp.com
Request Headers 如下:
:authority: proxy.mimvp.com :method: GET :path: /usercenter/ :scheme: https accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 accept-encoding: gzip, deflate, br accept-language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7,pt;q=0.6 cookie: MIMVPSESSID=3oe2pomu70vslug768b918g15b; Hm_lvt_51e3cc975b346e7705d8c255164036b3=1578826758,1579225430,1579229078,1579229082; userinfo=NmTiVmtvapW12cGE6Mzp7czoxMDoidXNlcl9lbWFpbCI7czozOToiTm1UaVZtdHZhcFcxMmNITmhaRzFwYmtCdGFXMTJjQzVqYjIwTzBPIjtzOjg6InVzZXJfcHdkIjtzOjU3OiJObVRpVm10dmFwVzEyY0dWbU0yTTVPVGsxT1RSbE5XSXdabUk1TmpWbU56VTBZekV5WVRaak1EaGkiO3M6MTM6InVzZXJfcmVtZW1iZXIiO3M6MTk6Ik5tVGlWbXR2YXBXMTJjREVPME8iO30O0O; Hm_lpvt_51e3cc975b346e7705d8c255164036b3=1579323376 dnt: 1 referer: https://proxy.mimvp.com/sadmin/ sec-fetch-mode: navigate sec-fetch-site: same-origin sec-fetch-user: ?1 upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
Response Headers 如下:
cache-control: no-store, no-cache, must-revalidate content-encoding: gzip content-type: text/html; charset=UTF-8 date: Sat, 18 Jan 2020 13:32:14 GMT expires: Thu, 19 Nov 1981 08:52:00 GMT pragma: no-cache server: nginx set-cookie: userinfo=MmTiRmtvapW12cGE6Mzp7czoxMDoidXNlcl9lbWFpbCI7czozOToiTW1UaVJtdHZhcFcxMmNITmhaRzFwYmtCdGFXMTJjQzVqYjIwTzBPIjtzOjg6InVzZXJfcHdkIjtzOjU3OiJNbVRpUm10dmFwVzEyY0dWbU0yTTVPVGsxT1RSbE5XSXdabUk1TmpWbU56VTBZekV5WVRaak1EaGkiO3M6MTM6InVzZXJfcmVtZW1iZXIiO3M6MTk6Ik1tVGlSbXR2YXBXMTJjREVPME8iO30O0O; expires=Sat, 01-Feb-2020 13:32:14 GMT; Max-Age=1209600; path=/ status: 200 vary: Accept-Encoding vary: proxys-zjk1 X-DNS-Prefetch-Control: off
设置session生命周期的也有2种方法
第一种 setcookie()
$lifetime=60;// 保存60秒,即1分钟 session_start(); setcookie(session_name(),session_id(),time()+$lifetime,"/");
直接用setcookie设置session id的生命周期。
第二种 session_set_cookie_params()
$lifetime=60;// 保存60秒,即1分钟 session_set_cookie_params($lifetime); session_start(); session_regenerate_id(true);
session_regenerate_id(); 方法用于改变当前session_id的值,并保留session中数组的值。
参数默认为false,如果设置为true则改变session_id的值,并清空当前session数组。
Cookie 生效时间
在一个页面设置cookie时,必须刷新或到下一个页面(刷新或跳转)才可以用 $_COOKIE 得到变量的值
原因是当页面第一次被浏览器访问载入时,页面中的 cookie 会被初始化设置,将其发送存储到客户端指定的存储位置,所以$_COOKIE没有接收到客户端发送过来的 cookie 变量的值,当刷新或到下一个页面时客户端会在页面程序在服务器端运行之前,发送与该地址相对应的cookie到服务器端,所以 $_COOKIE 可以得到的值!
说白了就是当每一个页面被访问时,如果客户端找到了与访问地址相对应的 cookie 时,程序会在服务器端运行之前发送这个 cookie 到服务器端.
php中设置cookie数组的时候,不可以用像php中的那个添加数据的方法:
<?php setcookie('my_cookie[]', 1); setcookie('my_cookie[]', 2); print_r($_COOKIE); // Array ( [my_cookie] => Array ( [0] => 1 )) // 数组的值添加是添加成功了,不过索引没有变, 后面的数据将前面的数据覆盖了! // 由此得到 my_cookie[],默认指向数据的第一元素的位置,即索引为0 的位置. // 注意与php中的不一样! 以后用cookie数据记住要指定数组元素索引 0,1,2... 哦! $my_cookie[] = 1; $my_cookie[] = 2; print_r($my_cookie); //Array ( [0] => 1 [1] => 2) ?>
删除 cookie 变量的两个方法:
1、php
<?php setcookie('user_name_1', 'proxy.mimvp.com', time()+3600); // 生存期为 1 个小时 setcookie('user_name_2', 'proxy.mimvp.com', time()+3600); // 生存期为 1 个小时 ?>
2、php
<?php setcookie('user_name_1'); // 第一种删除 setcookie('user_name_2', "", time()-1); // 第二种删除 print_r($_COOKIE); // 刷新页面,会输出 Array ( [user_name_1] => ) /* 为什么超级全局变量 $_COOKIE 中的 user_name_1 没有被删除(变量为空并不代表不存在),而user_name_2被删除了? 那是因为两个删除变量的方式不同! 第一种: 是设置了 cookie 的生存期, 只不过是将它的值默认设置为空, 生存期为与浏览器一样,浏览器关闭时,cookie才会删除! 所以,当重新打开一个浏览器,输出地址时,才会发现 cookie 变量全部被删除了! 将2.php 中两个 setcookie() 函数部分注释掉看看(重新输出了地址)! 第二种: 也是设置了 cookie 的生存期,是使 cookie 的生存期一定过期, cookie 也就被删除, 所以刷新页面,客户端向服务器端发送 cookie 时, $_COOKIE 并没有能够得到该cookie变量的值! */ ?>
会话id默认储放在客户端Cookie中
<?php session_start(); print_r($_COOKIE); ?>
cookie的设置有两种方法
1)header('set-cookie:user=proxy.mimvp.com');
2)setcookie('user', 'proxy.mimvp.com');
会话变量不能被GET数据或POST数据重载!
使用session变量传递数组,对象时无需序列化!
使用session变量传递对象时,在调用session_start()之前,必须包含该对类对象的定义,反序列化
(serialize)也是如此!
删除单个会话变量可以使用unset($_SESSION['xxx']) 直接删除!
删除所有的会话变量不可以用unset($_SESSION),因为这样会将所有的会话信息删除,包含存储在COOKIE中的PHPSESSID,也就是破坏了两个页面之间的会话联系,应该使用$_SESSION = array(); 消除会话id,使页面之间失去联系!
session_destroy();
程序清单1.1
<?php session_start(); header('content-type:text/html;charset=utf-8'); $_SESSION['a'] = 'a'; $_SESSION['b'] = 'b'; unset($_SESSION); // 测试后,再注释下看看 $_SESSION['user'] = 'proxy.mimvp.com'; echo 'SESSION_ID: '.session_id().'<br />'; echo '<a href="3.php" target="_blank">测试 3.php</a>'; ?> <?php session_start(); echo $_SESSION['user']; echo session_id(); // 会话变量改变了 ?>
会话id(session_id)的两种方式传递
1. cookie
2. url
因为默认session是基于cookie的,而cookie又是跟随http协议发送的,所以与cookie一样,在session_start()之前不能有任何输出!
现在主要说一说第二种,通过 url 传递会话id
php中已经定义SID这个常量来得到 会话的id
sesssin_id 的使用!
<?php session_start(); echo defined('SID')?'true':'false'; // true echo SID; // 什么也没有? ?>
为什么SID的值会是null 呢?是它哪里有问题了?
原因是因为 session 默认是基于 cookie 的,而 SID 只有 session_id 通过 url 传递数据时才会被赋值!
在浏览器中将 cookie 禁用,你就会发现 SID 有了输出,而不是 null!
删除 session
要三步实现
<?php session_destroy(); // 第一步: 删除服务器端session文件,这使用 setcookie(session_name(),'',time()-3600); // 第二步: 删除实际的session: $_SESSION = array(); // 第三步: 删除$_SESSION全局变量数组 ?>
大家都知道session变量是保存在服务器端的,也就是说session的变量会保存在服务器中一个目录中,可以在php.ini中的session.save_path 那里可以找到session文件中保存的地址,默认为 /tmp 并注释掉了 ;session.save_path = "/tmp"
默认的session的生存期是浏览的关闭就结束,但要知道会话过期结束后,当打开页面session_start()会判断会话id 是否存在,如果不存在就创建一个,否则将该会话id 的变量载入页面!
因为过期session_id会被创建一个新的,但它保存在服务器端的session文件并没有被删除(关闭浏览器,打开session文件保存地看看),所以要用session_destory()函数清除会话id,并同时清除相应的会话文件,这样的话才能做到最彻底的清除!
session_id 使用 url 传递session 变量数据时,因为session_start()开启会话时会判断会话id 是否存在,如果不存在就创建一个,否则将该会话id 的变量载入页面!
而现在是使用url 来传递session_id,然而每一次 刷新/进入页面 都会生成一个会话id,所以页面之间就不能得到在另一页面设置过的session_id 的变量,那么使用 session也就没什么意义了!
解决方法:
在session_start()之前,手动设置页面的session_id,这样页面的就可以得到前一页中所设置的session变量的,也就实现了会话的传递,如下代码可以说明!
//已禁用 cookie
1.php
<?php session_start(); $_SESSION['user'] = 'proxy.mimvp.com'; echo '<a href="2.php?'.SID.'">下一页</a>'; ?>
1.php
第4行代码也可以写成:echo '<a href="2.php">下一页</a>';
可以设置php.ini 中的 session.use_trans_sid 为1,这样当使用 url 传递会话 id 时,浏览器会自动将 session_id 追加到 url 的后面!
就好像在浏览器中 输入: proxy.mimvp.com 一样,浏览器会自动将其更换成 https://proxy.mimvp.com
2.php
<?php // 手动设置session_id,这种就可以使用前一个页面的session_id 的变量了,也就实现了会话! session_id($_GET['PHPSESSID']); session_start(); print_r($_SESSION); ?>
session 常用函数
bool session_start(void); 初始化session bool session_destroy(void): 删除服务器端session关联文件。 string session_id() 获取当前session的id string session_name() 获取当前存取的session名称, 也就是客户端保存session ID的cookie名称. 默认PHPSESSID, 可在 php.ini 中修改为 MIMVPSESSID 等。 array session_get_cookie_params() 与这个session相关联的session的细节. string session_cache_limiter() 控制使用session的页面的客户端缓存 ini session_cache_expire() 控制客户端缓存时间 bool session_destroy() 删除服务器端保存session信息的文件 void session_set_cookie_params ( int lifetime [, string path [, string domain [, bool secure [, bool httponly]]]] )设置与这个session相关联的session的细节 bool session_set_save_handler ( callback open, callback close, callback read, callback write, callback destroy, callback gc )定义处理session的函数,(不是使用默认的方式) bool session_regenerate_id([bool delete_old_session]) 分配新的session id
参考推荐:
Linux curl 命令模拟 POST/GET 请求 (推荐)
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2020-01-18 22:10:41
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!